23.Promise(2)

86 阅读3分钟

上一章讲了Promise的一些基本原理,本章主要是promise的一些api和异步的终极实现方案.

Promise.all

接受一个数组(也可以是es6的Map,Set可迭代的),数组元素可以是promise实例,也可以是常量,如果都成功返回一个数组对接参数数组的值,有一个失败就返回失败的结果.可以用于多个请求的结果作为下一个请求的参数.接上文MyPromise类

    static all(promises) {
          const values = [];
          const resolvedCount = 0;
          return new MyPromise((resolve, reject) => {
            //遍历promise获取每个promise的结果
            promises.forEach((p, index) => {
              MyPromise.resolve(p).then(
                //成功的时候需要放入数组中
                (value) => {
                  resolvedCount++;
                  values[index] = value;
                  if (resolvedCount == promises.length) {
                    resolve(values);
                  }
                },
                (reason) => {
                  //只要一个失败了,return的promise就失败
                  reject(reason);
                }
              );
            });
          });
        }

Promise.race

接受一个数组(也可以是es6的Map,Set可迭代的),数组元素可以是promise实例,也可以是常量.竞跑机制,谁先完成就返回谁.

        static race(promise) {
          //返回一个pomise
          return new MyPromise((resolve, reject) => {
            MyPromise.resolve(p).then(
              //一旦有成功,return成功
              (value) => {
                resolve(value);
              },
              //一旦有失败,return失败
              (reason) => {
                reject(reason);
              }
            );
          });
        }

Promise.allSettled

可以获取数组中每个 promise 的结果,无论成功或失败.数组元素对象形式{状态,值},适用于无依赖关系的数组

    static allSettled(promises) {
          const values = [];
          const count = 0;
          return new MyPromise((resolve, reject) => {
            //遍历promise获取每个promise的结果
            promises.forEach((p, index) => {
              MyPromise.resolve(p).then(
                //成功的时候需要放入数组中
                (value) => {
                  count++;
                  values[index] = { status: 'fulfilled', value};
                  if (count == promises.length) {
                    resolve(values);
                  }
                },
                (value) => {
                 count++;
                 values[index] = { status: 'rejected', value}
                 if (count == promises.length) {
                    resolve(values);
                  }
                }
              );
            });
          });
        }

Promise.any

与Promise.all相反只要有一个成功就返回

    static all(promises) {
          const values = [];
          const rejectCount = 0;
          return new MyPromise((resolve, reject) => {
            //遍历promise获取每个promise的结果
            promises.forEach((p, index) => {
              MyPromise.resolve(p).then(
                (value) => {
                  //只要一个成功了,return的promise就成功
                  reject(value);
                },
                (reason) => {
                  rejectCount++;
                  values[index] = reason;
                  if (rejectCount == promises.length) {
                    reject(reason);
                  }
                }
              );
            });
          });
        }
  • 多个异步并行,且相互没有关联,使用Promise.allSettled()

  • 多个异步并行,相互之间有依赖,使用Promise.all()

  • 多个异步并行,最终结果根据第一个出结果(不论成功还是失败)的 promise 而定,使用Promise.race()

  • 多个异步并行,最终结果根据第一个成功的 promise 而定,使用Promise.any()

异步终极方案 async await

async 异步函数

用于声明异步函数,返回值为一个 Promise 对象,它以类似 同步 的方式来写异步方法,语法与声明函数类似,如果return 了值,就相当于resolve值,没有retuen相当于reject状态,函数的返回值可以只用.then或者.catch来接.

await 等待

所谓 等待 其实就是指暂停当前 async function 内部语句的执行,等待后面的 myPromise() 处理完返回结果后,继续执行 async function 函数内部的剩余语句;myPromise() 是一个 Promise对象,而自定义的变量 value 则用于获取 Promise 对象返回的 resolve 状态值; async await是一对语法糖 await必须在async内部使用,可以让await开始的所有代码同步执行. await后面的Promise可能会失败 需要装在cry..catch里面

实现原理

ES7的generator和yield 生成器和迭代器. async 函数就是将 Generator 函数的星号(*)替换成 async,将 yield 替换成await