1. finally (cb) {
  2. return this.then(
  3. value => Promise.resolve(cb()).then(() => value),
  4. reason => Promise.resolve(cb()).then(() => { throw reason })
  5. );
  6. }

Promise.race

  1. Promise._race = promises => new Promise((resolve, reject) => {
  2. promises.forEach(promise => {
  3. promise.then(resolve, reject)
  4. })
  5. })
  6. Promise.myrace = function(iterator) {
  7. return new Promise ((resolve,reject) => {
  8. try {
  9. let it = iterator[Symbol.iterator]();
  10. while(true) {
  11. let res = it.next();
  12. console.log(res);
  13. if(res.done) break;
  14. if(res.value instanceof Promise) {
  15. res.value.then(resolve,reject);
  16. } else {
  17. resolve(res.value)
  18. }
  19. }
  20. } catch (error) {
  21. reject(error)
  22. }
  23. })
  24. }

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。

  1. // 以下 demo,请求两个 url,当两个异步请求返还结果后,再请求第三个 url
  2. const p1 = request(`http://some.url.1`)
  3. const p2 = request(`http://some.url.2`)
  4. Promise.all([p1, p2])
  5. .then((datas) => { // 此处 datas 为调用 p1, p2 后的结果的数组
  6. return request(`http://some.url.3?a=${datas[0]}&b=${datas[1]}`)
  7. })
  8. .then((data) => {
  9. console.log(msg)
  10. })

Promise.all原理实现

  1. function promiseAll(promises){
  2. return new Promise(function(resolve,reject){
  3. if(!Array.isArray(promises)){
  4. return reject(new TypeError("argument must be anarray"))
  5. }
  6. var countNum=0;
  7. var promiseNum=promises.length;
  8. var resolvedvalue=new Array(promiseNum);
  9. for(var i=0;i<promiseNum;i++){
  10. (function(i){
  11. Promise.resolve(promises[i]).then(function(value){
  12. countNum++;
  13. resolvedvalue[i]=value;
  14. if(countNum===promiseNum){
  15. return resolve(resolvedvalue)
  16. }
  17. },function(reason){
  18. return reject(reason)
  19. )
  20. })(i)
  21. }
  22. })
  23. }
  24. var p1=Promise.resolve(1),
  25. p2=Promise.resolve(2),
  26. p3=Promise.resolve(3);
  27. promiseAll([p1,p2,p3]).then(function(value){
  28. console.log(value)
  29. })

Promise.all错误处理

有时候我们使用Promise.all()执行很多个网络请求,可能有一个请求出错,但我们并不希望其他的网络请求也返回reject,要错都错,这样显然是不合理的。如何做才能做到promise.all中即使一个promise程序reject,promise.all依然能把其他数据正确返回呢?

1、全部改为串行调用(失去了node 并发优势)
2、当promise捕获到error 的时候,代码吃掉这个异常,返回resolve,约定特殊格式表示这个调用成功了
**

  1. var p1 =new Promise(function(resolve,reject){
  2. setTimeout(function(){
  3. resolve(1);
  4. },0)
  5. });
  6. var p2 = new Promise(function(resolve,reject){
  7. setTimeout(function(){
  8. resolve(2);
  9. },200)
  10. });
  11. var p3 = new Promise(function(resolve,reject){
  12. setTimeout(function(){
  13. try{
  14. console.log(XX.BBB);
  15. }
  16. catch(exp){
  17. resolve("error");
  18. }
  19. },100)
  20. });
  21. Promise.all([p1, p2, p3]).then(function (results) {
  22. console.log("success")
  23. console.log(results);
  24. }).catch(function(r){
  25. console.log("err");
  26. console.log(r);
  27. });