废话不多说,来分析以下Promise是怎么运行的 ?
远古时期,我写过一篇MyPromise的实现
这篇文章揭示了Promise就是使用oop将传统callback队列放到自己的成员变量实现而已,这篇文章缺点在于没有阐述值传透(以后填)。
我们来剖析以下代码,在Promise内部到底做了什么?
new Promise((resolve,reject)=> { // p1
setTimeout(function(){
resolve(22)
},1000)
})
.then(value=> { // p2
console.log('promise2')
})
.then(()=>{ // p3
console.log('promise3')
})
我将它分为2个阶段
一、回调函数的加载
实际上,下面这部分代码,称为excutor
(resolve,reject)=> {
setTimeout(function(){
resolve(22)
},1000)
}
excutor 在Promise对象创建后是立刻执行的,但众所周知,setTimeout只是将函数放进异步队列,当主线程空闲时才执行.所以
它并不是等到异步函数执行时,才执行then的,此时已经执行then了
它并不是等到异步函数执行时,才执行then的,此时已经执行then了
它并不是等到异步函数执行时,才执行then的,此时已经执行then了
它的过程如下:
- p1的创建
- p1.excutor (异步队列+1)
- p1.then(cb1)
- p2创建
- p2.excutor()
- p1.asyncArr.push(包装过的cb1)
- p2.then(cb2)
- p3创建
- p3.excutor()
- p2.asyncArr.push(包装过的cb2)
二、异步任务执行
主线程终于执行完毕了,此时
- 异步调用
- p1.resolve(22)
- 包装过的cb1(它闭包保存了p2.resolve)
- 执行原装cb1(22) ,并缓存其结果x(undefined)
- p2.resolve(x)
- 包装过的cb2(它闭包保存了p3.resolve)
- 执行原装cb2(undefined) ,并缓存其结果x(undefined)
- p3.resolve(x)
- p3的异步数组空空如也
这就是Promise的链式调用,通过then创建多个Promise,通过前一个Promise实例保存后一个实例的resolve,一次触发,多个受用
两个独立的过程源码
这文章的代码运行分析源码在
https://juejin.im/post/5aa7868b6fb9a028dd4de672#heading-10
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
function Promise(excutor) {
let self = this
this.status = PENDING
this.value = undefined
this.reson = undefined
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
function resolve(value) {
if (value instanceof Promise) {
return value.then()
}
setTimeout(() => {
if (self.status === PENDING) {
self.status = FULFILLED
self.value = value
self.onFulfilledCallbacks.forEach(cb => cb(self.value))
}
})
}
function reject(reson) {
setTimeout(() => {
if (self.status === PENDING) {
self.status = REJECTED
self.reson = reson
self.onRejectedCallbacks.forEach(cb => cb(self.value))
}
})
}
try {
excutor(resolve, reject);
} catch (e) {
reject(e);
}
}
function resolvePromise(nextPromise, data, resolve, reject) {
if (nextPromise === data) {
return reject(new TypeError('循环引用'))
}
let called = false
if (data instanceof Promise) {
if (data.status === PENDING) {
data.then(value => {
resolvePromise(nextPromise, value, resolve, reject)
}, reson => {
reject(reson)
})
} else {
data.then(resolve, reject);
}
} else if (data !== null && (typeof data === 'object') || (typeof data === 'function')) {
try {
let then = data.then
if (typeof then === 'function') {
then.call(data, value => {
if (called) return
called = true
resolvePromise(nextPromise, value, resolve, reject)
}, reson => {
if (called) return
called = true
reject(reson)
})
}
} catch (e) {
if (called) return
called = true
reject(e)
}
} else {
resolve(data)
}
}
Promise.prototype.then = function (onFulfilled, onRejected) {
const that = this;
let nextPromise;
// 处理参数默认值 保证参数后续能够继续执行
onFulfilled =
typeof onFulfilled === "function" ? onFulfilled : value => value;
onRejected =
typeof onRejected === "function" ? onRejected : reason => {
throw reason;
};
if (that.status === FULFILLED) { // 成功态
return nextPromise = new Promise((resolve, reject) => {
setTimeout(() => {
try {
let data = onFulfilled(that.value);
resolvePromise(nextPromise, data, resolve, reject); // 新的promise resolve 上一个onFulfilled的返回值
} catch (e) {
reject(e); // 捕获前面onFulfilled中抛出的异常 then(onFulfilled, onRejected);
}
});
})
}
if (that.status === REJECTED) { // 失败态
return nextPromise = new Promise((resolve, reject) => {
setTimeout(() => {
try {
let data = onRejected(that.reason);
resolvePromise(nextPromise, data, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
if (that.status === PENDING) { // 等待态
// 当异步调用resolve/rejected时 将onFulfilled/onRejected收集暂存到集合中
return nextPromise = new Promise((resolve, reject) => {
that.onFulfilledCallbacks.push((value) => {
try {
let data = onFulfilled(value);
resolvePromise(nextPromise, data, resolve, reject);
} catch (e) {
reject(e);
}
});
that.onRejectedCallbacks.push((reason) => {
try {
let data = onRejected(reason);
resolvePromise(nextPromise,data, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
};
new Promise((resolve,reject)=> {
setTimeout(function(){
resolve(22)
},1000)
})
.then(value=> {
console.log('promise2')
})
.then(()=>{
console.log('promise3')
})
网友评论