finally (cb) {return this.then(value => Promise.resolve(cb()).then(() => value),reason => Promise.resolve(cb()).then(() => { throw reason }));}
Promise.race
Promise._race = promises => new Promise((resolve, reject) => {promises.forEach(promise => {promise.then(resolve, reject)})})Promise.myrace = function(iterator) {return new Promise ((resolve,reject) => {try {let it = iterator[Symbol.iterator]();while(true) {let res = it.next();console.log(res);if(res.done) break;if(res.value instanceof Promise) {res.value.then(resolve,reject);} else {resolve(res.value)}}} catch (error) {reject(error)}})}
Promise.all
Promise.all方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。(Promise.all方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
Iterator(遍历器)
我们都知道 JavaScript 中对数组有很多种遍历方式,但是如果我们想像数组那样去遍历其他数据,我们该怎么办呢?Iterator遍历器就为我们提供了这种机制。 Iterator 是一个接口,它为 JavaScript 中的各种数据结构提供了一种规范。任何数据结构只要部署了 Iterator 接口,那么我们就可以使用 for…of 遍历这个数据结构 在 JavaScript 中部署了 Iterator 接口的有Array、String、Map、Set。 Iterator 的遍历过程是这样的。 (1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。 (2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。 (3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。 (4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。 我们可以通过 Symbol.iterator 属性获取到遍历器
对于 Promise.all(arr) 来说,在参数数组中所有元素都变为决定态后,然后才返回新的 promise。
// 以下 demo,请求两个 url,当两个异步请求返还结果后,再请求第三个 urlconst p1 = request(`http://some.url.1`)const p2 = request(`http://some.url.2`)Promise.all([p1, p2]).then((datas) => { // 此处 datas 为调用 p1, p2 后的结果的数组return request(`http://some.url.3?a=${datas[0]}&b=${datas[1]}`)}).then((data) => {console.log(msg)})
Promise.all原理实现
function promiseAll(promises){return new Promise(function(resolve,reject){if(!Array.isArray(promises)){return reject(new TypeError("argument must be anarray"))}var countNum=0;var promiseNum=promises.length;var resolvedvalue=new Array(promiseNum);for(var i=0;i<promiseNum;i++){(function(i){Promise.resolve(promises[i]).then(function(value){countNum++;resolvedvalue[i]=value;if(countNum===promiseNum){return resolve(resolvedvalue)}},function(reason){return reject(reason))})(i)}})}var p1=Promise.resolve(1),p2=Promise.resolve(2),p3=Promise.resolve(3);promiseAll([p1,p2,p3]).then(function(value){console.log(value)})
Promise.all错误处理
有时候我们使用Promise.all()执行很多个网络请求,可能有一个请求出错,但我们并不希望其他的网络请求也返回reject,要错都错,这样显然是不合理的。如何做才能做到promise.all中即使一个promise程序reject,promise.all依然能把其他数据正确返回呢?
1、全部改为串行调用(失去了node 并发优势)
2、当promise捕获到error 的时候,代码吃掉这个异常,返回resolve,约定特殊格式表示这个调用成功了
**
var p1 =new Promise(function(resolve,reject){setTimeout(function(){resolve(1);},0)});var p2 = new Promise(function(resolve,reject){setTimeout(function(){resolve(2);},200)});var p3 = new Promise(function(resolve,reject){setTimeout(function(){try{console.log(XX.BBB);}catch(exp){resolve("error");}},100)});Promise.all([p1, p2, p3]).then(function (results) {console.log("success")console.log(results);}).catch(function(r){console.log("err");console.log(r);});
