参考:
- 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
})