zoukankan      html  css  js  c++  java
  • 自定义promise

    /*
          自定义promise
            1. 执行MyPromise构造函数,要立即执行executor
            2. promise实例对象,内部有三种状态
              初始化 pending
              成功 resolved
              失败 rejected
              注意:状态只能修改一次
                  如果executor内部出错了,promise状态改成rejected
            3. then方法的实现
              promise.then(onResolved, onRejected)      
                promise的状态是resolved时,异步调用onResolved函数
                promise的状态是rejected时,异步调用onRejected函数
                promise的状态是pending时,不调用函数。
                  未来promise可能会变化,此时还是要异步调用相应的函数
            4. promise.then().then()  
              then方法返回值是promise,才能链式调用
              返回值promise对象的状态:
                1. 如果内部没有返回值 / 返回值不是promise 就是resolved
                2. 如果内部返回值是promise 看promise的状态
                3. 如果内部抛异常,就是rejected    
        */
     
    function MyPromise(executor) {
            this._value = undefined;
            this._status = 'pending';
            this._callbacks = [];

            const resolve = (value) => {
              if (this._status === 'pending') {
                this._status = 'resolved';
                this._value = value;
                this._callbacks.length &&
                  this._callbacks.forEach((cb) => cb.onResolve(value));
              }
            };

            const reject = (reason) => {
              if (this._status === 'pending') {
                this._status = 'rejected';
                this._value = reason;
                this._callbacks.length &&
                  this._callbacks.forEach((cb) => cb.onReject(reason));
              }
            };

            try {
              executor(resolve, reject);
            } catch (e) {
              reject(e);
            }
          }

          MyPromise.prototype.then = function (onResolve, onReject) {
      // 如果onResolved存在,不变
           // 如果onResolved不存在,说明catch触发的。 如果是成功状态promise,保证返回值还是一个成功状态promise
            onResolve = onResolve ? onResolve : (value) => value;
          // then方法一旦只传一个参数,并且是失败状态promise,保证返回值 是 失败状态promise内部的值
            onReject = onReject
              ? onReject
              : (reason) => {
                  throw reason;
                };

            return new MyPromise((resolve, reject) => {
              setTimeout(() => {
                switch (this._status) {
                  case 'resolved':
                    setPromiseStatus(onResolve, this._value, resolve, reject);
                    break;
                  case 'rejected':
                    setPromiseStatus(onReject, this._value, resolve, reject);
                    break;

                  default:
                    this._callbacks.push({
                      onResolve(value) {
                        setPromiseStatus(onResolve, value, resolve, reject);
                      },
                      onReject(reason) {
                        setPromiseStatus(onReject, reason, resolve, reject);
                      },
                    });
                    break;
                }
              });
            });
          };

          function setPromiseStatus(onFn, value, resolve, reject) {
            try {
              let result = onFn(value);
              result instanceof MyPromise
                ? result.then(resolve, reject)
                : resolve(result);
            } catch (e) {
              reject(e);
            }
          }

          MyPromise.prototype.catch = function (onReject) {
            return this.then(undefined, onReject);
          };

          MyPromise.resolve = function (value) {
            return new MyPromise((resolve, reject) => {
              resolve(value);
            });
          };

          MyPromise.reject = function (reason) {
            return new MyPromise((resolve, reject) => {
              reject(reason);
            });
          };

          MyPromise.prototype.finally = function (onResolve) {
            return new MyPromise((resolve, reject) => {
              if (this._status === 'pending') {
                this._callbacks.push({
                  onResolve,
                  onReject: onResolve,
                });
              } else {
                onResolve(this._value);
              }
            });
          };

          MyPromise.all = function (promises) {
            let resolveCount = 0,
              resolveArr = [];

            return new MyPromise((resolve, reject) => {
              for (let i = 0; i < promises.length; i++) {
                const element = promises[i];
                element.then((value) => {
                  resolveCount++;
                  resolveArr[i] = value;

                  if (resolveCount === promises.length) {
                    resolve(resolveArr);
                  }
                }, reject);
              }
            });
          };

          let p = new MyPromise((resolve, reject) => {
            // setTimeout(() => {
            // resolve(123);
            reject(0);
            // }, 1000);
          });

          p.then((value) => {
            console.log(111, value);
          })
            .catch((value) => {
              console.log(222, value);
            })
            .then((value) => {
              console.log(333, value);
              return MyPromise.reject(999);
            })
            .catch((value) => {
              console.log(444, value);
            })
            .finally((value) => {
              console.log(555, value);
            });
          // console.log(p);
          // console.log(MyPromise.resolve(123));

          // 测试promise.all
          const p1 = new MyPromise((resolve, reject) => {
            setTimeout(() => {
              resolve(111);
            }, 2000);
          });
          const p2 = new MyPromise((resolve, reject) => {
            setTimeout(() => {
              reject(222);
            }, 2000);
          });

          let a = MyPromise.all([p1, p2]);
          console.log(a);
  • 相关阅读:
    java学习day62-Spring boot整合Shiro配置
    java学习day62-springboot中的拦截
    java学习day62-DB项目-首页菜单动态显示
    疯狂学java的第26天
    疯狂学java的第25天
    疯狂学java的第24天
    疯狂学java的第23天
    疯狂学java的第22天
    疯狂学java的第21天
    疯狂学java的第20天
  • 原文地址:https://www.cnblogs.com/wangsai-666/p/14724082.html
Copyright © 2011-2022 走看看