首页 > 其他分享 >promise.all()详解

promise.all()详解

时间:2023-08-03 13:55:10浏览次数:37  
标签:resolve console log 详解 Promise result catch promise

promise.all详解

promise.all中所有的请求成功了,走.then(),在.then()中能得到一个数组,数组中是每个请求resolve抛出的结果。
promise.all中只要有一个失败了,走.catch(),在.catch()中获取第一个失败请求rejected抛出的结果。

在 Promise.all 中,如果其中任何一个 Promise 被 rejected 或抛出异常,则整个 Promise.all 将会立即被 reject,而不会等到其他 Promise 完成。

具体地说,一旦一个 Promise 失败,Promise.all 就会中止并返回一个新的拒绝状态的 Promise。然后**,其他未完成的 Promise 将会继续运行,但是它们的结果将会被忽略,不会进一步处理。
//有一个失败
Promise.all([
    Promise.resolve({
        code:200,
        data:[1,2,3]
    }),
    Promise.reject({
        code:500,
        data:[]
    }),
    Promise.resolve({
        code:200,
        data:[7,8,9]
    }),

]).then(res => {
    console.log(res)
    console.log("成功")
}).catch(err => {
    console.log(err)
    console.log("失败")
})
打印结果: {code: 500, data: Array(0)}
//所有都成功
Promise.all([
    Promise.resolve({
        code:200,
        data:[1,2,3]
    }),
    Promise.resolve({
        code:200,
        data:[4,5,6]
    }),
    Promise.resolve({
        code:200,
        data:[7,8,9]
    }),

]).then(res => {
    console.log(res)
    console.log("成功")
}).catch(err => {
    console.log(err)
    console.log("失败")
})

打印结果: [{…}, {…}, {…}]  成功


问题:当有一个请求失败时,如何拿到其他成功请求的返回值并只提示一次报错

const promises = [
  fetch('url1').then(response => response.json()),
  fetch('url2').then(response => response.json()),
  fetch('url3').then(response => response.json()),
];

Promise.all(promises.map(promise => promise.catch(error => ({ error }))))
  .then(results => {
    const errors = results.filter(result => result.error);
    const data = results.filter(result => !result.error);
    
    if (errors.length > 0) {
      console.error('One or more requests failed.');
    }
    
    console.log('Successful results:', data);
  });

在上述示例中,我们使用 fetch 函数作为示例请求,并将返回的 Promise 放入一个数组中。然后,我们使用 promises.map() 方法,将每个 Promise 进行一个 .catch() 处理,将失败的 Promise 转换为一个包含错误信息的对象

在 Promise.all 中,我们处理了这些经过 .catch() 处理的 Promise 数组,得到一个新的 Promise.all 对象。在 then 回调中,我们对结果进行过滤,提取出成功和失败的结果。然后我们根据失败结果的数量来决定是否输出错误提示,以及输出成功结果。

这样,即使有一个请求失败,我们仍然可以获取其他成功请求的返回值,并只提示一次错误。

详细解释https://blog.csdn.net/weixin_62765236/article/details/127018532

Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

promise.all()该方法用于将多个Promise实例,包装成一个新的Promise实例。

var p=Promise.all([p1,p2,p3]);

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

promise.all()

比如当数组里的P1,P2都执行完成时,页面才显示。
值得注意的是,返回的数组结果顺序不会改变,即使P2的返回要比P1的返回快,顺序依然是P1, P2

Promise.all成功返回成功数组,失败返回失败数据,一但失败就不会继续往下走

let p1 = new Promise((resolve, reject) => {
  resolve('成功了')
})
 
let p2 = new Promise((resolve, reject) => {
  resolve('success')
})
 
let p3 = Promse.reject('失败')
 
Promise.all([p1, p2]).then((result) => {
  console.log(result)               //['成功了', 'success']
}).catch((error) => {
  console.log(error)
})
 
Promise.all([p1,p3,p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)      // 失败了,打出 '失败'
})
let wake = (time) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`${time / 1000}秒后醒来`)
    }, time)
  })
}
 
let p1 = wake(3000)
let p2 = wake(2000)
 
Promise.all([p1, p2]).then((result) => {
  console.log(result)       // [ '3秒后醒来', '2秒后醒来' ]
}).catch((error) => {
  console.log(error)
})
 
需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和
Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果
获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,
偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,
使用Promise.all毫无疑问可以解决这个问题。
注意:如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,
并不会触发Promise.all()的catch方法。
 
示例代码:
 
const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result)
.catch(e => e);
 
const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result)
.catch(e => e);
 
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));// ["hello", Error: 报错了]
 
p1会resolved,p2首先会rejected,但是p2有自己的catch方法,该方法返回的是一个
新的 Promise 实例,p2指向的实际上是这个实例。
该实例执行完catch方法后,也会变成resolved,导致Promise.all()方法参数里面的两个实
例都会resolved,因此会调用then方法指定的回调函数,而不会调用catch方法指定的回调函数。
 
而如果p2没有自己的catch方法,就会调用Promise.all()的catch方法。如下:
 
const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result);
 
const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result);
 
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));// Error: 报错了

promise.race( )

Promise.race是赛跑的意思,也就是说Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败

使用场景: Promise.all和Promise.race都是有使用场景的。 有些时候我们做一个操作可能得同时需要不同的接口返回的数据,这时我们就可以使用Promise.all; 有时我们比如说有好几个服务器的好几个接口都提供同样的服务,我们不知道哪个接口更快,就可以使用Promise.race,哪个接口的数据先回来我们就用哪个接口的数据

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
  },1000)
})
 
let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('failed')
  }, 500)
})
 
Promise.race([p1, p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)  // 打开的是 'failed'
})

下面来看几个简洁易懂的例子:

1.await 可以获得多个promise 的返回结果

2.Promise.all 返回的也是promise,所以可以直接await Promise.all();

1. 使用Promise

function fn(){
    return new Promise((resolve,reject)=>{
        let randomNum = parseInt(Math.random()*6+1);
        console.log(randomNum);
        if(randomNum>3){
            resolve('买'); 
        }
        else{
            reject('不买');
        }
    })
}
Promise.all([fn(),fn()]).then(
  (x)=>{console.log(x,'success')},(y)=>{console.log(y,'error');
});

Promise.all 里面参数为一个数组,数组的每一项是一个返回promise 的函数调用
then 的第一个参数是所有promise都成功的调用,返回结果是一个数组,数组的每一项为函数promise 的返回结果。
then 的第二个参数:返回结果有一个失败则执行失败的回调,拿到的是第一个失败的值

2. 使用await

await 是可以获得多个promise 返回结果的,Promise.all()返回的也是promise结果。所以想要使用await 拿到多个promise的返回值,可以直接await Promise.all();

function fn(){
    return new Promise((resolve,reject)=>{
        let randomNum = parseInt(Math.random()*6+1);
        console.log(randomNum);
        if(randomNum>3){
            resolve('买'); 
        }
        else{
            reject('不买');
        }
    })
}
async function test(){
    try{
    let res = await Promise.all([fn(),fn()]);
    console.log(res,'success');
    }
    catch(error){
        console.log(error,'error');
    }
}
test();

Promise.all([fn(),fn()]) 都返回resolve(); 才能够拿到成功的返回值
Promise.all([fn(),fn()]) 有一个返回reject(), 则进入catch(error), 拿到失败的返回值

标签:resolve,console,log,详解,Promise,result,catch,promise
From: https://www.cnblogs.com/hxy--Tina/p/17603131.html

相关文章

  • Linux 驱动程序模块详解
    Linux驱动程序模块是一种可执行代码,用于管理硬件设备。通常,驱动程序模块是以源代码形式进行开发的,然后编译成二进制模块,最后加载到Linux内核中。以下是关于Linux驱动程序模块的详细介绍:1、模块分类根据驱动程序用途的不同,Linux驱动程序模块可以分为多个类型,包括字符设备驱动程序、......
  • StoneDB 源码解读系列|Tianmu 引擎工具类模块源码详解(一)
    StoneDB源码解读系列文章正式开启,预计以周更的形式跟大家见面,请多多支持~本篇源码解读内容已进行直播分享,可在视频号观看直播回放,也可点击阅读原文跳转至B站观看回放视频。PPT内容可在社区论坛中查看下载:https://forum.stonedb.io/t/topic/89各个工具类属于Tianmu引擎的......
  • 消息队列详解
    文章目录1、什么是消息队列2、消息队列特点3、消息队列的的传输模式4、常用的消息队列1、什么是消息队列消息队列一般简称为MQ(MessgesQueue),是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成,是在消息的传输过程中保存消息的容器。......
  • 算法-10--python shuffle函数_python中shuffle()方法的功能详解
     pythonshuffle函数_python中shuffle()方法的功能详解: python的概率分布中,洗牌算法是通过shuffle()方法实现的,shuffle()方法将列表的所有元素打乱,随机排列。Python既可以使用random.shuffle对列表进行洗牌,也可以使用random.shuffle随机播放字符串列表,本文向大家介绍python中......
  • JavaScript中的 "return await promise" 与 "return promise"
    原文地址:'returnawaitpromise'vs'returnpromise'inJavaScript原文作者:DmitriPavlutin译文出自:翻译计划当从异步功能中返回时,您可以等待该承诺得到解决,或者您可以直接返回它:returnawaitpromisereturnpromise:jsasyncfunctionfunc1(){constpromise=asyncOperat......
  • seaborn的详解-线性关系04
    线性关系可视化许多数据集都有着众多连续变量。数据分析的目的经常就是衡量变量之间的关系,我们之前介绍了可以绘制双变量分布的函数。然而,使用统计模型来估计两个噪声观测组之间的简单关系可能是非常有帮助的。我们在这一章中讨论的函数功能将在线性回归的框架实现。 请注意,seabor......
  • Nginx详解
    Nginx:强大的Web服务器和反向代理服务器一、简介Nginx是一款开源的Web服务器和反向代理服务器,广泛应用于互联网应用和网络托管领域。其具有高可靠性、高性能和高扩展性,能够轻松处理大量并发请求,保证服务器资源的有效利用和网络流量的均衡分配。Nginx的主要特点包括高效的事件处理机......
  • MySQL内存分配详解
    InnoDB存储引擎层基础内存分配如果在编译MySQL的时候不开启FPS的监控,InnoDB对动态内存(heap)的分配和释放使用基础的new、delete、malloc、free等。默认InnoDB对内存的分配和回收会添加FPS的监控模块。InnoDB对动态内存(heap)的分配和回收使用封装后的函数,主要在ut_allocator类中实......
  • 基础 | 详解3D结构光如何标定
    结构光视觉的优点:非接触、信息量大、测精度高、抗干扰能力强。结构光视觉传感器参数的标定包括:摄像机参数标定、结构光平面参数标定。结构光视觉测量原理图我们不考虑镜头的畸变,将相机的成像模型简化为小孔成像模型,则特征点的图像坐标Pf与其在摄像机坐标系下的三维坐标P之......
  • 请求头详解——Headers
    请求头定义:客户端,即浏览器通过输入url后确定等于做了一次向服务器的请求动作,在这个请求里面带有请求参数,请求参数的集合即为请求头。请求头的参数(常用的):Accept:浏览器可接收的文件类型Accept-Charset:浏览器可以接收的编码类型Accept-Encoding:浏览器可以接收的压缩编码类型Ac......