Promise(期约)扩展方法实现

2022 年 8 月 22 日 星期一
/
11

阅读此文章之前,你可能需要首先阅读以下的文章才能更好的理解上下文。

Promise(期约)扩展方法实现

代码实现

前面的章节中我们的PromisePolyfill类实现了Promise(期约)的基本模型,下面介绍一下其静态扩展方法resolverejectallallSettleraceany的实现。

class PromisePolyfill {
  constructor(executor) {
    //...
  }
  //该函数一旦执行,将内部的这两个回调函数赋值
  then(onFulfilled, onRejected) {
        //...
  }
  //注意这个catch捕获的是最后一个reject
  catch(onRejected) {
    //...
  }
  static resolve(res) {
    return new PromisePolyfill((resolve, reject) => {
      resolve(res);
    });
  }
  static reject(reason) {
    return new PromisePolyfill((resolve, reject) => {
      reject(reason);
    });
  }
  static all(promiseArray) {
    return new PromisePolyfill((resolve, reject) => {
      const values = [];
      promiseArray.forEach((promise) => {
        promise
          .then((res) => {
            values.push(res);
            if (values.length === promiseArray.length) resolve(values);
          })
          .catch((err) => {
            reject(err);
          });
      });
    });
  }
  static allSettle(promiseArray) {
    return new PromisePolyfill((resolve, reject) => {
      const results = [];
      promiseArray.forEach((promise) => {
        promise
          .then((res) => {
            results.push({ status: PROMISE_STATUS_FULFILLED, result: res });
            if (results.length === promiseArray.length) resolve(results);
          })
          .catch((err) => {
            results.push({ status: PROMISE_STATUS_REJECTED, result: err });
            if (results.length === promiseArray.length) resolve(results);
          });
      });
    });
  }
  static race(promiseArray) {
    return new PromisePolyfill((resolve, reject) => {
      promiseArray.forEach((promise) => {
        promise.then(resolve, reject);
      });
    });
  }
  static any(promiseArray) {
    // 要执行resolve必须等到有一个成功的结果
    // 要执行reject所有的都失败才执行reject
    return new PromisePolyfill((resolve, reject) => {
      let rejectArr = [];
      promiseArray.forEach((promise) => {
        promise.then(resolve, (err) => {
          rejectArr.push(err);
          if (rejectArr.length === promiseArray.length) {
            reject(new Error('all promises reject'));
          }
        });
      });
    });
  }
}

测试

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script src="./index.js"></script>
    <script>
      PromisePolyfill.resolve('PromisePolyfill.resolve').then(res => {
        console.log(res);
      })
      PromisePolyfill.reject('PromisePolyfill.reject').then(res => {
        console.log(res);
      }).catch(err => {
        console.log(err);
      })
      PromisePolyfill.all([new PromisePolyfill((resolve,reject) => {
        resolve(123)
      }),new PromisePolyfill((resolve,reject) => {
        resolve(456)
      }) ]).then(res => {
        // console.log(res);
      })
      PromisePolyfill.allSettle([new PromisePolyfill((resolve,reject) => {
        resolve(123)
      }),new PromisePolyfill((resolve,reject) => {
        reject(456)
      })]).then(res => {
        // console.log(res);
      })
      PromisePolyfill.race([new PromisePolyfill((resolve,reject) => {
        resolve(456)
      }),new PromisePolyfill((resolve,reject) => {
        resolve(123)
      })]).then(res => {
        // console.log(res);
      })
      PromisePolyfill.any([new PromisePolyfill((resolve,reject) => {
        reject(456)
      }),new PromisePolyfill((resolve,reject) => {
        reject(123)
      })]).then(res => {
        console.log(res);
      }).catch(err => {
        console.log(err);
      })
    </script>
  </body>
</html>

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...