mc-congxueda

导航

 

Promise 对象有三种状态:pendingfullfilled 和 rejected,分别代表了 promise 对象处于等待、执行成功和执行失败状态。

创建 promise 对象后处于pending状态,pending状态可以转化为fullfilledrejected状态,但不能逆向转化,且转化过程只能有一次,即resolvereject后不能再resolvereject。因此需要在 promise 对象中持有状态的引用,通过添加一个名为_state(为了说明是内部属性,用户不要直接使用,属性名前加了下划线,后面同理)的属性实现。现在 Promise 构造函数定义如下

function Promise(resolver) {
    this._status = 'pending';
}
Promise.prototype.then = function(onResolve, onReject) {
    var promise = new Promise(function() {});
    ...
    return promise;
}

 

 

那么如何实现promise呢?先观察一下promise的样子

let  a = new Promise((resolve,reject)=>{
       // dosomething
       resolve()  
})

 

function PromiseFn(callBack){
        let self = this;
        self.resolveVal = undefined;
        self.rejectVal = undefined;
        self.status = 'pending'//默认是等待状态
        
        function resolve(val){
            if(self.status === 'pending'){
                self.resolveVal = val;
                self.status = 'resolve'
            }
        }
        function reject(val){
            if(self.status === 'pending'){
                self.rejectVal = val;
                self.status = 'reject'
            }
        }     //这里要注意,try catch若是写在 let self = this 会报错,let存在暂时死区,没有常规的变量提升。必须先申明后使用     // callback执行,调用resolve函数。
        try{
            callBack(resolve,reject)//callback进来自动执行
        }catch(e){
            reject()//若是有报错,则直接变为reject状态
        }
    }

上面这一步,需要注意的是callback是立即执行的。下面这段会立即打印111

 

let  a = new Promise((resolve,reject)=>{
       console.log('111')
})console.log('456')

上面我们定义了 resolveVal 和 rejectVal,因为待会在promise调用then执行的时候,会作为参数传参给resolveFunticon或者rejectFunction

 

下面一起看看promise.then吧,promise.then(resolveFunticon,rejectFunction)。在promise的原型链上有个then方法

PromiseFn.prototype.then = function(resolveFunction,rejectFunction){
  let self = this;
  if(self.status === 'resolve'){
    resolveFunction(self.resolveVal)
  }
  if(self.status === 'reject'){
    rejectFunction(self.rejectVal)
  }
}

 

 

在then执行的时候,去判断内部是啥状态,然后执行对应的resolve或者reject回调函数

let promiseA = new PromiseFn((resolve,reject)=>{
         resolve('成功啦')
})
promiseA.then((resolveVal)=>{
    console.log('resolve'+resolveVal)
},(rejectVal)=>{
    console.log('reject'+rejectVal)

 

 

参考

 

posted on 2022-09-26 11:59  MC~大叔  阅读(421)  评论(0)    收藏  举报