js 实现 promise

本文仅用于个人技术记录,如误导他人,概不负责。

本文有参考其他文章,不过地址忘了~~~。

===========================================================

上代码

const PROMISE_STATUS = {
  PENDING: 'PENDING',
  FULFILLED: 'FULFILLED',
  REJECTED: 'REJECTED'
}

class ModelPromise {
    static promiseId = 1;
  constructor(initFn) {
    if (typeof initFn !== 'function') {
      throw new Error('must be function')
    }
        this.promiseId = ModelPromise.promiseId;
    this.promiseStatus = PROMISE_STATUS.PENDING;
    this.promiseValue = undefined;
    this.onFulfilledStack = [];
    this.onRejectStack = [];
        this.finallyCallback = undefined;

    initFn(this._resolve.bind(this), this._reject.bind(this));
        
        ModelPromise.promiseId++;
  }

  _resolve(resolveValue) {
    if (this.promiseStatus !== PROMISE_STATUS.PENDING) { return; }

    const runFulfilled = (value) => {
      let onFulfilled;
      while (onFulfilled = this.onFulfilledStack.shift()) {
        onFulfilled(value);
      }
            if (this.finallyCallback) {this.finallyCallback()}
    }

    const runRejected = (error) => {
      let onReject;
      while (onReject = this.onRejectStack.shift()) {
        onReject(error);
      }
            if (this.finallyCallback) {this.finallyCallback()}
    }
        
        const run = () => {
            if (resolveValue instanceof ModelPromise) {
                // 有父子依赖关系时候父值将由子值决定
                resolveValue.then((value) => {
                    this.promiseStatus = PROMISE_STATUS.FULFILLED;
                    this.promiseValue = value;
                    runFulfilled(value);
                }, (err) => {
                    this.promiseStatus = PROMISE_STATUS.REJECTED;
                    this.promiseValue = err;
                    runRejected(err);
                });
            } else {
                this.promiseStatus = PROMISE_STATUS.FULFILLED;
                this.promiseValue = resolveValue;
                runFulfilled(resolveValue);
            }
        }

    setTimeout(run);
  }

  _reject(err) {
        if (this.promiseStatus !== PROMISE_STATUS.PENDING) { return; }
        
        const run = () => {
            this.promiseStatus = PROMISE_STATUS.REJECTED;
            this.promiseValue = err;
            
            let onReject;
      while (onReject = this.onRejectStack.shift()) {
        onReject(error);
      }
        }
    setTimeout(run);
  }

  then(onFulfill, onReject) {
    let _resolveNext;
    let _rejectNext;
        /* 生成一个新的promise等待返回 */
    let newPromise = new ModelPromise((resolve, reject) => {
      _resolveNext = resolve;
      _rejectNext = reject;
    });
        
        const runFulfilled = value => {
            try {
                if (typeof onFulfill !== 'function') {
                    _resolveNext(value);
                } else {
                    let onFulfillReturn = onFulfill(value);
                    
                    if (onFulfillReturn instanceof ModelPromise) {
                        onFulfillReturn.then(_resolveNext, _rejectNext);
                    } else {
                        _resolveNext(onFulfillReturn);
                    }
                }
            } catch(err) {
                _rejectNext(err);
            }
        }
        
        const runRejected = error => {
            try {
                if (typeof onReject !== 'function') {
                    _resolveNext(value);
                } else {
                    let onRejectedReturn = onReject(error);
                    
                    if (onRejectedReturn instanceof ModelPromise) {
                        onRejectedReturn.then(_resolveNext, _rejectNext);
                    } else {
                        _rejectNext(onRejectedReturn);
                    }
                }
            } catch(err) {
                _rejectNext(err);
            }
        }
        
        
    if (this.promiseStatus === PROMISE_STATUS.FULFILLED) {
      runFulfilled(this.promiseValue);
    } else if (this.promiseStatus === PROMISE_STATUS.REJECTED) {
      runRejected(this.promiseValue);
    } else {
            /* important!!!! */
            /* 此时推入栈中待执行的不是onFulfill, 而是runFulfilled */
            /* 核心需要关注的是,当一个函数在resolve之后,应当执行then函数的回调函数并且返回值赋值给下一个promise,_resolveNext(onRejectedReturn); */
      this.onFulfilledStack.push(runFulfilled);
      this.onRejectStack.push(runRejected);
    }
    return newPromise;
  }

  catch (catchFn) {
    this.then(undefined, catchFn);
  }
    
    finally(finallyCallback) {
        this.finallyCallback = finallyCallback;
    }
    
    static resolve(value) {
        // 如果需要处理的本身就是一个promise,则直接返回使用这个promise
        if (value instanceof ModelPromise) return value;
    let newPromise = new ModelPromise(resolve => {
      resolve(value);
    });
    return newPromise;
  }
    
    static reject(value) {
    let newPromise = new ModelPromise(resolve, reject => {
      reject(value);
    });
    return newPromise;
  }
    
    static race(promiseArr) {
        let newPromise = new ModelPromise((resolve, reject) => {
            promiseArr.forEach((item, index) => {
                if (item instanceof ModelPromise) {
                    item.then(res => {
                        resolve(res);
                        checkAllResolve();
                    }, err => {
                        reject(err);
                    });
                } else {
                    resolve(item);
                }
            });
    });
    return newPromise;
    }
    
    static all(promiseArr) {
    let newPromise = new ModelPromise((resolve, reject) => {
            let promiseValArr = []; //保存所有promise的value,按顺序;
            
            const checkAllResolve = () => {
                if (promiseValArr.length === promiseArr.length) {
                    resolve(promiseValArr);
                }
            }
            
            promiseArr.forEach((item, index) => {
                promiseValArr[index] = undefined;
                if (item instanceof ModelPromise) {
                    item.then(res => {
                        promiseValArr[index] = res;
                        checkAllResolve();
                    }, err => {
                        reject(err);
                    });
                } else {
                    promiseValArr[index] = item;
                    checkAllResolve();
                }
                
            });
            
      
    });
    return newPromise;
  }
}


/* test start */

let p1 = new ModelPromise((resolve, reject) => {
  console.log("同步执行");
  setTimeout(() => {
    resolve('第一次resolve的值');
    console.log(p1);
    console.log(p2);
    console.log(p3);
    console.log(p4);
    console.log(p5);
  }, 1000);
});

let p2 = p1.then((res) => {
  console.log('after then1', res);
  return new ModelPromise((resolve, reject) => {
        resolve('新promise的返回值');
    });
})

let p3 = p2.then((res) => {
  console.log('after then2', res);
  return new ModelPromise((resolve, reject) => {
        setTimeout(() => {
            resolve('3S 后再执行的结果');
        }, 3000);
    });
});
// console.log(promise1);

let p4 = p1.then((res) => {
  console.log('接收到第一次resolve的值', res);
  return '第二次then的返回值';
});
// console.log(promise2);

let p5 = p3.then((res) => {
    console.log('接收到第二次resolve的值', res);
})
.catch((err) => {
    console.log('捕获错误', err);
});

/* let promiseAll = ModelPromise.all([p1, p2, p3]).then(res => {
    console.log('promiseAll', res);
}); */

let promiseAll = ModelPromise.race([p1, p2, p3]).then(res => {
    console.log('promise race', res);
});

promiseAll.finally(() => {
    console.log('promiseAll finally');
});

猜你喜欢

转载自www.cnblogs.com/AlexBlogs/p/10852704.html