手写 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)