3

参考:

返回值

如果参数是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
})

更多学习笔记请戳这里~


6fafa
45 声望2 粉丝