参考:
- Promise.resolve()与new Promise(r => r(v))
- new Promise((resolve)=>{resolve()}) 与 Promise.resolve() 等价吗
- 探讨:当Async/Await的遇到了EventLoop
返回值
如果参数是promise实例,前者返回新期约,后者原样返回:
let p = new Promise((r)=>{r("123")})
//Promise.resolve将原封不动返回这个实例
p === Promise.resolve(p) //true
//new Promise() 返回一个新期约
let p2 = new Promise((r)=>{
r(p)
})
p2 !== p //true
参数是一个thenable对象, 都返回新的解决期约:
let thenable = {
then: function(resolve,reject){
resolve("123")
}
}
let p1 = new Promise((r)=>{ //p1: Promise {<fulfilled>: "123"}
r(thenable)
})
let p2 = Promise.resolve(thenable) //p2: Promise {<fulfilled>: "123"}
then的执行时机
new Promise(r => r(v))的then()回调会被推迟两个时序(事件循环):
console.log("script start")
let v = new Promise((resolve)=>{
console.log("v start")
resolve("v resolve")
})
let p1 = new Promise((resolve)=>{
console.log(1)
resolve(v)
}).then((v)=>{
console.log(v)
})
new Promise((resolve)=>{
resolve()
}).then(()=>{
console.log(2)
}).then(()=>{
console.log(3)
}).then(()=>{
console.log(4)
}).then(()=>{
console.log(5)
})
console.log("script end")
//"script start"
//"v start"
//1
//"script end"
//2
//3
//v resolve 推迟了两个循环
//4
//5
而Promise.resolve(v)都then()则正常:
console.log("script start")
let v = new Promise((resolve)=>{
console.log("v start")
resolve("v resolve")
})
Promise.resolve(v).then((v)=>{
console.log(v)
})
new Promise((resolve)=>{
resolve()
}).then(()=>{
console.log(2)
}).then(()=>{
console.log(3)
}).then(()=>{
console.log(4)
}).then(()=>{
console.log(5)
})
console.log("script end")
//"script start"
//"v start"
//"script end"
//"v resolve"
//2
//3
//4
//5
原因:
- 这是因为浏览器发现resolve的是另一个promise时(假设称原promise为promiseA,另一个promise为promiseB),会创建一个名为 PromiseResolveThenableJob的任务去处理promiseB,而这个任务是一个微任务
- 等到promiseB被resolved之后,会再生成去处理promiseA(resolvePromiseA)的微任务
- 执行完resolvePromiseA微任务,才会执行promiseA的then,因此推迟了两个事件循环
- 而Promise.resolve()的then正常执行,是因为参数是promiseB时,会不做处理返回promiseB本身
可以用伪代码将PromiseResolveThenableJob表示为:
let promiseA = new Promise((resolve)=>{
resolve(promiseB)
}).then(()=>{
console.log("123")
})
//PromiseResolveThenableJob的伪代码,可以理解成
promiseB.then(()=>{
resolvePromiseA,
rejectPromiseA
})
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。