手写 promise


1、基本架构搭建

function Promise(fn) {
    this.promiseState = 'pending' // 状态
    this.promiseResult = undefined // 结果

    var resolve = function(){

    }
    var reject = function() {

    }

    fn(resolve,reject)
}

Promise.prototype = {
    then: function() {

    }
}

 

 2、resolve,reject 状态的改变和结果的保存 ,并且状态改变是单向的不可逆的

回调函数的调用是window 所以这里要注意 this 的指向

 3、throw 抛出异常改变状态

1 var p = new Promise(function (resolve, reject) {
2     throw('抛出异常')
3 })
4 console.log(p)

当promise回调直接抛出异常的时候,直接报错,后面的代码不会执行

 所以 try catch 处理回调函数

捕获到交给 reject处理

4、then 方法

then 方法我的理解就是 当状态改变时 调用的回调函数

 两个参数,根据状态只执行一个

var p = new Promise(function (resolve, reject) {
    throw('抛出异常')
})
p.then(function(res){
    console.log(res)
},function(err){
    console.log(err)
})
console.log(p)

js

Promise.prototype = {
    then: function(onFulfilled,onRejected) {
        if(this.PromiseState === 'fulfilled'){
            onFulfilled(this.PromiseResult)
        }
        if(this.PromiseState === 'rejected'){
            onRejected(this.PromiseResult)
        }
    }
}

5、改为异步任务执行

这里总结,改为异步其实就是把then中的回调保存起来,等状态改变再执行

Promise.prototype = {
    then: function(onFulfilled,onRejected) {
        if(this.PromiseState === 'fulfilled'){
            onFulfilled(this.PromiseResult)
        }
        if(this.PromiseState === 'rejected'){
            onRejected(this.PromiseResult)
        }
        if(this.PromiseState === 'pending'){
            // 保存回调函数
            this.thenCallback = { onFulfilled, onRejected }
        }
    }
}

// 当状态改变 判断 thenCallback  ,然后执行

 1  var resolve = function(res){
 2         if(_this.PromiseState !== 'pending') return
 3         _this.PromiseState = 'fulfilled'
 4         _this.PromiseResult = res
 5         if(_this.thenCallback) {
 6             _this.thenCallback.onFulfilled(res)
 7         }
 8     }
 9     var reject = function(err) {
10         if(_this.PromiseState !== 'pending') return
11         _this.PromiseState = 'rejected'
12         _this.PromiseResult = err
13         if(_this.thenCallback) {
14             _this.thenCallback.onRejected(err)
15         }
16     }

当然,这里个人觉得可以优化的地方,then中只做回调函数的保存这一步的操作,回调函数的执行放到 resolve,reject (状态改变时)中执行,这样可以减少几个状态的判断

 

 6、then中多个回调的实现


当 then 多个回调的时候 我们发现 只执行了最后一个 then

 所以我们要弄一个 队列数组保存,

当转台改变是 执行数组中的所有函数

 if(_this.thenCallback) {
            _this.thenCallback.forEach(item => {
                item.onFulfilled(res)
            })
        }

 7、then 结果返回(Promise,return,throw)

js