群里看到,不懂就查,查不懂就对线源码。javascript
Promise.resolve().then(() => {
console.log(0)
return Promise.resolve(4)
}).then(res => {
console.log('res: ', res)
})
Promise.resolve().then(() => {
console.log(1);
}).then(() => {
console.log(2);
}).then(() => {
console.log(3);
}).then(() => {
console.log(5);
}).then(() =>{
console.log(6);
})
复制代码
1 2 3 4 5 6
java
首先设1
为.then(() => { console.log(1) })
这一个微任务,promise
其余同理。markdown
一开始执行完两个Promise.resolve()
之后:异步
microTask: `0 1`
复制代码
Promise.resolve(4)
返回一个状态为fulfilled
的Promise
此时按逻辑应该把4
加入到微任务中了,oop
可是在then
中返回fulfilled
状态的Promise
的话,ui
Promise
内部会将返回的Promise
的then
方法执行放入到微任务队列中执行。this
microTask: 1 Promise.resolve(4).then
microTask: Promise.resolve(4).then 2
复制代码
而then
内部由于Promise.resolve(4)
状态已是fulfilled
了,google
又申请了个微任务为了让0
同步Promise.resolve(4).then
的fulfilled
的状态,spa
由于须要等Promise.resolve(4).then
内部暴露的Promise
初始化完毕后再执行,
因此须要一个微任务等待。
(实际为:Promise.resolve(4).then
返回的Promise
须要一个微任务进行同步Promise.resolve(4)
返回的Promise
的fulfilled
状态,在同步时顺便也把外部0
返回的Promise
一并同步了)
注:0
返回的Promise
是同步Promise.resolve(4).then
的状态
microTask: 2 同步状态
microTask: 同步状态 3
microTask: 3 4
最后输出: 1 2 3 4 5 6
复制代码
0
修改成
.then(() => {
console.log(0)
// return Promise.resolve(4)
return {
then(resolve) {
console.log('then')
resolve(4)
},
}
})
复制代码
输出:
0
1
then
2
res: 4
3
5
6
复制代码
能够看到then
方法是放入了微任务队列中的。
这个then
方法中resolve
执行直接同步fulfilled
状态到0
返回的Promise
状态上,所以执行完then
方法下一个微任务就是输出res
了。
我翻找了v8
在4.3.65
版本还未使用v8 Torque(tq v8内部语言)或C
实现的promise.js
的源码,在5版本之后就使用C实现了,最新版本使用tq
实现。
经过看源码可知Promise.resovle(x)
至关于new Promise(rs => rs(x))
,二者行为一致,有兴趣能够试试。
首先介绍一下deferred
,deferred
指内部为了链式调用建立的对象,在then
方法被调用时返回的就是deferred
,Promise
的deferred
对象也是个Promise
(废话,不这样咋链式
据上面源码可知Promise.then
/返回Thenable
都会建立这个对象。据我感受最新返回Thenable
并不会建立这个对象,直接使用外部的deferred
对象
function PromiseDeferred() {
if (this === $Promise) {
// Optimized case, avoid extra closure.
var promise = PromiseInit(new $Promise(promiseRaw));
return {
promise: promise,
resolve: function(x) { PromiseResolve(promise, x) },
reject: function(r) { PromiseReject(promise, r) }
};
} else {
var result = {};
result.promise = new this(function(resolve, reject) {
result.resolve = resolve;
result.reject = reject;
})
return result;
}
}
复制代码
=>
为返回,->
为步骤,deferred Object
简称为deferred
注:以后的"同步状态"微任务只针对非pending
状态
then(onResolve) => deferred
-> onResolve => Promise(fulfilled)
-> Promise(fulfilled).then(deferred.resolve, deferred.reject)
-> 放入一个微任务"同步状态"到外部 deferred 上
-> 以便链式调用
then(onResolve) => deferred
-> onResolve => Thenable
-> deferred.resolve(Thenable)
-> then(onResolve).then(onResolve2, onReject2)
-> deferred.promise.then(onResolve2, onReject2)
-> 不调用这个 .then 据我理解是不会将 Thenable 对象转换成 defeerred 的
-> deferred.promise PromiseState is fulfilled
-> 执行 then 方法,onResolve2 在内部会被包装所以
-> 执行中 Thenable 转换成 thenDeferred 时同步执行 then 方法
-> 根据 then 方法执行后决定 thenDeferred.promise 状态
-> thenDeferred.promise.then(onResolve, onReject)
-> 挂载 deferred.promise.then 的参数到 thenDeferr.promise.then 上
复制代码
返回Thenable
对象:
Promise.resolve()
.then(() => {
console.log(0)
return {
then(resolve) { // 在4.x源码中这儿是同步执行
console.log('then')
resolve(4)
},
}
})
.then(res => {
console.log('res: ', res)
})
至关于
Promise.resolve()
.then(() => {
console.log(0)
})
.then(() => { // 在4.x源码中这儿是同步执行
console.log('then')
return 4
})
.then(res => {
console.log('res: ', res)
})
复制代码
这是在4.3.65
版本的实现逻辑(个人理解,有误您对
返回Promise
都是须要一个微任务,可是Thenable
又不须要,可是这是4.多的代码实现,以后代码改动很大,不过思路大致一致。(应该吧,我看不懂后面的了太菜了
由于这是4.3.65
的代码了,因此不符合以前推理的逻辑也正常,虽然这个版本的代码已经挺优雅了,可是可能为了更优雅的实现,Thenable
/Promise
的then
要一视同仁,也得放进微任务中执行,不必作特殊处理,因此两个的then
方法都进入了微任务队列中处理。(我寻思挺合理的
其次个人源码理解的返回Thenable
对象的promise
后面得再跟一个then
方法才会执行Thenable.then
,因此须要改动并统一行为。(多是我理解错误?
那么为何在目前的版本就是返回Promise
是要两个微任务,而Thenable
仍是一个
据我推测在以后版本中,只要有Then
都会放入微任务队列执行一下,若是是Promise
:
同步状态其实至关于往一个promise
的then
方法传入(deferred.resolve, deferred.reject)
简称这个行为为同步d
。
不讨论rejected
状态(或者说和 fulfilled
状态差很少
PromiseState is fulfilled/Thenable Object:
设 Promise.resolve().then() 返回的 deferred 为 d
Promise.resolve().then(() => Promise.resolve(4))
-> Promise.resolve(4) => Promise(fulfilled) 且非 deferred
-> 内部处理
-> 有 then 方法进行劫持放进微任务队列中执行
-> 因为 then 方法未传入参数, 默认为 onResolve = x => x
-> 即 Promise(fulfilled).then(x => x)
-> pending 状态须要同步
-> Promise(fulfilled).then(x => x).then(同步d)
-> 以上是按照 4.x 逻辑来的,不过 then 方法变成异步罢了
Promise.resolve().then(() => ({ then(rs) { rs(4) }})
-> Thenable 在微任务被调用 then 方法时内部会传入 d.resolve, d.reject 来直接同步外部,
-> 所以只须要一个微任务执行 then 方法便可
新的内部实现应该比这优雅,可是惋惜我看不懂
Promise.resolve(4).then(res => res) -> PromiseState is pending:
将当前的promise.then中放入同步状态微任务,
以即可以同步状态到deferred对象上
好比:
Promise.resolve().then(() => Promise.resolve(4).then(res => res))
Promise.resolve().then() 返回的是 deferred(d)
Promise.resolve(4).then(res => res) 返回的也是 deferred(thenD)
由于须要同步状态,所以内部处理挂载上去
Promise.resolve(4).then(res => res).then(同步d)
以便d能及时更新状态
复制代码
前面代码改为
Promise.resolve()
.then(() => {
console.log(0)
return Promise.resolve(4).then(res => res) // pending 状态挂载同步状态微任务
}).then(res => {
console.log('res: ', res)
})
复制代码
输出:0 1 2 3 4 5 6
一时兴起,大胆猜想,人菜想写,若有错误,轻骂。
内部实现写的好致使的结果,我反正信了。(doge