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)
它会返回一个新的 promise 因为久的promise 的状态已经改变了,所以旧的promise已经失效
then(onResolve, onRejected) { // 添加任务队列
// 因为状态只能单向改变,如果之前resolve了,后面then中throw抛出异常则无法改变状态
// 另外任务队列也不是最新的
// 所以不能 return this
return new mpromise((resolve, reject) => {}
}
接下来, then 里面的回调函数有两种情况,
一种返回结果
var res = p.then(function(res) { console.log(res) return 'hello promise!' // return new mpromise((resolve) => { resolve('success')}) }, (err) => { console.log(err) })
另一种直接返回一个 promise
var res = p.then(function(res) { console.log(res) return new mpromise((resolve) => { resolve('success')}) }, (err) => { console.log(err) })
还有一种是 throw 抛出错误
throw(‘1’)
所以要做一个区分判断
then(onResolve, onRejected) { // 添加任务队列
// 因为状态只能单向改变,如果之前resolve了,后面then中throw抛出异常则无法改变状态
// 另外任务队列也不是最新的
// 所以不能 return this
return new mpromise((resolve, reject) => {
if(this.promiseState === 'fulfilled') {
let res = onResolve(this.promiseResult)
if(res instanceof mpromise) { // 如果返回的还是一个 promise,则需要怎么处理
} else {
}
}
if(this.promiseState === 'rejected') {
let res = onRejected(this.promiseResult)
}
if(this.promiseState === 'pending') {
onResolve && this.resolveQueue.push(onResolve)
onRejected && this.rejectQueue.push(onRejected)
}
})
}
然后 我们要给新的then返回的promise加上结果和改变状态
如何获取结果并赋值给新的 promise promiseResult 呢?
then(onResolve, onRejected) { // 添加任务队列
// 因为状态只能单向改变,如果之前resolve了,后面then中throw抛出异常则无法改变状态
// 另外任务队列也不是最新的
// 所以不能 return this
return new mpromise((resolve, reject) => {
if(this.promiseState === 'fulfilled') {
setTimeout(() => {
try {
let res = onResolve(this.promiseResult)
if(res instanceof mpromise) { // 如果返回的还是一个 promise,则需要怎么处理
res.then(res => {resolve(res)}, err => {reject(err)})
} else {
resolve(res) // 改变新的 promise 里面的状态
}
} catch(err) {
reject(err)
}
})
}
if(this.promiseState === 'rejected') {
let res = onRejected(this.promiseResult)
if(res instanceof mpromise) { // 如果返回的还是一个 promise,则需要怎么处理
res.then(res => {resolve(res)}, err => {reject(err)})
} else {
reject(res) // 改变新的 promise 里面的状态
}
}
if(this.promiseState === 'pending') {
onResolve && this.resolveQueue.push(onResolve)
onRejected && this.rejectQueue.push(onRejected)
}
})
}
8、异步修改状态 then 方法结果返回(Promise,return,throw)
因为 同步的时候直接 走 fulfilled 和 rejected 条件里的方法(改变了状态和结果)
这时如果变成异步的话,我们会发现then 返回的新的promise是状态没改,结果为undefind

所以我们接下来处理一下 pending 的时候的情况,其实和上面两种情况差不多,
最后处理成
if(this.promiseState === 'pending') { onResolve && this.resolveQueue.push(function() { let res = onResolve(this.promiseResult) this.handleState(res, resolve, reject) }) onRejected && this.rejectQueue.push(function() { let res = onRejected(this.PromiseResult) handleState(res,resolve,reject) }) }
封装代码得
then(onResolve, onRejected) { // 添加任务队列
// 因为状态只能单向改变,如果之前resolve了,后面then中throw抛出异常则无法改变状态
// 另外任务队列也不是最新的
// 所以不能 return this
return new mpromise((resolve, reject) => {
if(this.promiseState === 'fulfilled') {
setTimeout(() => {
let res = onResolve(this.promiseResult)
this.handleState(res, resolve, reject)
})
}
if(this.promiseState === 'rejected') {
let res = onRejected(this.promiseResult)
this.handleState(res, resolve, reject)
}
if(this.promiseState === 'pending') {
onResolve && this.resolveQueue.push(function() {
let res = onResolve(this.promiseResult)
this.handleState(res, resolve, reject)
})
onRejected && this.rejectQueue.push(function() {
let res = onRejected(this.PromiseResult)
handleState(res,resolve,reject)
})
}
})
}
handleState(res,resolve,reject) {
if (res instanceof mPromise) {
// 如果返回的是一个promise
// 则调用 then获取这个 promise的 PromiseResult作为目前promie的 PromiseResult
res.then(res => {
// 调用 resolve 修改 PromiseResult
resolve(res)
}, err => {
reject(err)
})
} else {
resolve(res) // 这里有问题,并不是每次状态都是改成 fulfilled,后面再调整调整
}
}
9、catch 和 异常穿透 的实现
catch 其实在 then 中就已经实现了
catch(onRejected) { return this.then(undefined, onRejected) }
穿透的原理:
如果 onRejected 不传则抛出 err

相当于在then 中抛出错误一层一层传下去

到最下层 catch其实也是调用 then ,和其回调 reason => {console.warn(reason)} 的执行
mpromise.resolve = function() { return new mpromise((resolve, reject) => { if (val instanceof mPromise) { // 如果返回的是一个promise // 则调用 then获取这个 promise的 PromiseResult作为目前promie的 PromiseResult val.then(res => { // 调用 resolve 修改 PromiseResult resolve(res) }, err => { reject(err) }) } else { resolve(val) } }) } mpromise.reject = function(val) { return new mPromise((resolve,reject) => { // 无论传什么都是返回 reject reject(val) }) }
all的实现
返回一个有结果的 promise
和every方法类似,只要 有一个是 rejected 则返回 rejected 的值,状态为 rejected
全部都是fulfilled 则返回 fulfilled 数组的值, 状态为 fulfilled
mpromise.all = function(arr) { return new mpromise((resolve, reject) => { let array = [] for(let i = 0;i < arr.length; i++){ arr[i].then(res => { array.push(res) if(arr.length == array.length) { console.log(array) resolve(array) } }, err => { reject(err) }) } }) }
race 的实现
race 就是数组promise 中哪个状态先改变就 返回的promise,就使用该状态和值,
因为状态的改变是单向的,所以取到的状态是先改变状态
mpromise.race = function(promises) { return new mpromise((resolve, reject) => { for(let i = 0;i < promises.length; i++){ promises[i].then(r => { resolve(r) },e => { reject(e) }) } }) }
浙公网安备 33010602011771号