第 80 题:介绍下 Promise.all 使用、原理实现及错误处理
const p = Promise.all([p1, p2, p3]);
Promise.all 方法接受一个数组作为参数,p1、p2、p3 都是 Promise 实例,如果不是,就会先调用下面讲到的 Promise.resolve 方法,将参数转为 Promise 实例,再进一步处理。(Promise.all 方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(37)
借助楼上的代码,可以看出promise.a
ll虽然可以称为并发,依然是单线程的,和后端的并发实质性不一样.js的多线程并发可以借助cluster,各个子进程取到的结果统一返回给主进程进行管理,父子进程通讯机制与react父子组件通讯相似。
promise里面,形参resolve只执行一次的,你这里应该调用promise.resolve(p)来获取promise实例
学习了
兄得长城是不是要哭倒了
resolve(p)
这里有问题,因为p已经是一个Promise实例了,不需要resolve,状态发生改变(无论成功或失败)会自动进入then回调;如果此处resolve,会导致始终只能拿到一个promise的结果借鉴这两位兄台的代码: @irina9215 @luohong123
Promise.race
的实现牛逼
Promise._all = function(list) {
let resValue = []
let count = 0
}
var a = new Promise((resolve) => {
setTimeout(() => {
resolve(1000)
}, 1000)
})
var b = new Promise((resolve) => {
setTimeout(() => {
resolve(2000)
}, 1000)
})
Promise.all1([a, b]).then((c) => {
console.log(c)
})
Promise.all()的参数是传入一个数组,数组的值是Promise对象,这个函数返回一个Promise对象
这个函数顾名思义就是检查传入的所有数组是否都执行成功,如果都成功那么这个函数返回的Promise对象进入resolve状态并将所有promise成功的参数组成一个数组传给resolve函数,如果其中任何一个失败,那么就进入reject状态,并将第一个reject的promise的参数传给Promise.all返回的promise对象的reject函数
原理实现:
流下没有技术眼泪的第218天
说一下对处理异常方式的理解。const p = Promise.all([p1,p2])的特点是当参数数组中的promise实例p1、p2都返回resolved时p才会返回resloved,只要参数数组实例中有一个返回rejected时,p就会返回reject,另一个resolved的结果也没有被返回,所以这并不是我们想要的结果。怎么处理这种异常呢?
其实给数组中的promise实例定义了错误处理catch方法的时候,就不会在走p的catch的方法,且参数实例在执行完catch方法之后状态会变成resolved。
执行完catch方法后,也会变成resolved,导致Promise.all()方法参数里面的两个实例都会resolved,因此会调用then方法指定的回调函数,而不会调用catch方法指定的回调函数。
这段代码岂不是没有起到all的作用,只要有一个resolve, 就不会执行后面的promise了
两个结果分别是:
有问题欢迎指正!
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve
Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象。如果这个值是一个 promise ,那么将返回这个 promise ;
他写的问题在没用 Promise.resolvePromise.all 实现:
Promise.all 错误处理:
使用
try catch
,使 promise 不进入 reject 函数Promise.every
扩展,所有的 promise 都错误才触发 reject,否则一律返回Promise.all 使用
场景1: p1、p3 是 Promise 实例;p2 是普通变量
场景2:p1、p2 resolve;p3 reject,没有单独进行catch处理
场景3: p1、p2 resolve;p3 reject,catch 有处理
Promise.all 方法接受一个数组作为参数(可以不是数组,但必须具有 Iterator 接口),p1、p2、p3 都是 Promise 实例(如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例)。
Promise.all 原理实现
Promise.all 原理错误处理
p1、p2、p3 都 resolve,会触发 p 的 then 方法,参数 data 是数组,每一项取值对应该 Promise 实例 resolve 的值。
当 p1、p2、p3 没有实现自己 catch 方法时, 其中一个 reject,会触发 p 的 catch 方法,参数 error 是参数列表中第一个 reject 出来的值。
当 p1、p2、p3 有实现自己 catch 方法时, 其中一个 reject,触发 p 的 then 方法还是 catch 方法,取决于 Promise 实例 reject 后对应的 catch 方法是如何处理的。
all 是 Promise 的静态方法
你这里直接resolve(p)不对吧
如果无论成功或失败都执行 resolve,可以用
Promise.allSettled
更多
Promise.all(values),返回一个 promise 实例。如果迭代器中所有的 promise 参数状态都是 resolved, 则 promise 实例的状态为 resolved,其 PromiseValue 为每个参数的 PromiseValue 组成的数组;
如果参数中的 promise 有一个失败(rejected),此实例的状态为 rejected,其 PromiseValue 为是第一个失败 promise 的 PromiseValue
说all体验不好,那我们也可以自己做一个some方法,表示全部失败才算失败
一、Promise概念
Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一。Promise.all()接受一个由promise任务组成的数组,可以同时处理多个promise任务,当所有的任务都执行完成时,Promise.all()返回resolve,但当有一个失败(reject),则返回失败的信息,即使其他promise执行成功,也会返回失败。和后台的事务类似。和rxjs中的forkJoin方法类似,合并多个 Observable 对象 ,等到所有的 Observable 都完成后,才一次性返回值。
二、Promise.all如何使用
对于 Promise.all(arr) 来说,在参数数组中所有元素都变为决定态后,然后才返回新的 promise。
三、Promise.all原理实现
四、Promise.all错误处理
有时候我们使用Promise.all()执行很多个网络请求,可能有一个请求出错,但我们并不希望其他的网络请求也返回reject,要错都错,这样显然是不合理的。如何做才能做到promise.all中即使一个promise程序reject,promise.all依然能把其他数据正确返回呢?
1、全部改为串行调用(失去了node 并发优势)
2、当promise捕获到error 的时候,代码吃掉这个异常,返回resolve,约定特殊格式表示这个调用成功了
这么写的话是只要又一个promise失败, 整个.all 就失败了. 对业务是不是没那么友好
参考:使用Promise.all
Promise.all()方法将多个Promise实例包装成一个Promise对象(p),接受一个数组(p1,p2,p3)作为参数,数组中不一定需要都是Promise对象,但是一定具有Iterator接口,如果不是的话,就会调用Promise.resolve将其转化为Promise对象之后再进行处理。
使用Promise.all()生成的Promise对象(p)的状态是由数组中的Promise对象(p1,p2,p3)决定的;
1、如果所有的Promise对象(p1,p2,p3)都变成fullfilled状态的话,生成的Promise对象(p)也会变成fullfilled状态,p1,p2,p3三个Promise对象产生的结果会组成一个数组返回给传递给p的回调函数;
2、如果p1,p2,p3中有一个Promise对象变为rejected状态的话,p也会变成rejected状态,第一个被rejected的对象的返回值会传递给p的回调函数。
Promise.all()方法生成的Promise对象也会有一个catch方法来捕获错误处理,但是如果数组中的Promise对象变成rejected状态时,并且这个对象还定义了catch的方法,那么rejected的对象会执行自己的catch方法,并且返回一个状态为fullfilled的Promise对象,Promise.all()生成的对象会接受这个Promise对象,不会返回rejected状态。
过分了昂
今天又是流下没有技术的眼泪的一天?
哦