Discuss / JavaScript / Promise里resolve(arg)里的参数arg是Promise对象的情况

Promise里resolve(arg)里的参数arg是Promise对象的情况

Topic source

蓝田暖玉

#1 Created at ... [Delete] [Delete and Lock User]

按我的理解,resolve会把其参数交给then中的函数,作为回调的参数,但我发现这样一份代码,其中将第一个Promise对象传给了第二个Promise中的resolve,而回调函数是打印。但事实上,打印的不是Promise对象,最终打印的是第一个对象中resolve的参数。但then方法的调用者确确实实是第二个对象。注意这不是链式调用中return一个Promise的写法,而是Promise是参数。谁能解释一下这种情况下then为什么能获得非调用对象传过来的参数。

const setDelay = (millisecond) => {
  return new Promise((resolve, reject)=>{
      if (typeof millisecond != 'number') reject(new Error('参数必须是number类型'));
      setTimeout(()=> {
        resolve(`我延迟了${millisecond}毫秒后输出的`)
      }, millisecond)
  })
} // 第一个promise对象
const setDelaySecond = (seconds) => {
  return new Promise((resolve, reject)=>{
      if (typeof seconds != 'number' || seconds > 10) reject(new Error('参数必须是number类型,并且小于等于10'));
      setTimeout(()=> {
        console.log(`先是setDelaySeconds函数输出,延迟了${seconds}秒,一共需要延迟${seconds+2}秒`)
        resolve(setDelay(2000)) // 这里依赖上一个Promise
      }, seconds * 1000)
  })
} // 第二个promise对象
setDelaySecond(3).then((result)=>{
  console.log(result)  
}).catch((err)=>{
  console.log(err);
})

.

#2 Created at ... [Delete] [Delete and Lock User]

如果 then 中的回调函数返回一个未定状态(pending)的 Promise,那么 then 返回 Promise 的状态也是未定的,并且它的终态与那个 Promise 的终态相同;同时,它变为终态时调用的回调函数参数与那个 Promise 变为终态时的回调函数的参数是相同的。 

MDN上这句应该可以解释你这个问题吧

蓝田暖玉

#3 Created at ... [Delete] [Delete and Lock User]

then中的回调函数就是个打印语句,没有返回值

Waring

#4 Created at ... [Delete] [Delete and Lock User]

then里面先拿到的resolve返回的filled状态,然后执行函数体,不知道这样理解对不对

Deler

#5 Created at ... [Delete] [Delete and Lock User]

题主代码的输出结果:

先是setDelaySeconds函数输出,延迟了3秒,一共需要延迟5秒
我延迟了2000毫秒后输出的

试试把这句

 resolve(setDelay(2000)) // 这里依赖上一个Promise

改成

 resolve(setDelay(2000).then((str)=>{console.log("No pending.")})) // 这里依赖上一个Promise

则输出结果就变成了

先是setDelaySeconds函数输出,延迟了3秒,一共需要延迟5秒
No pending.
undefined

解释:

因为resolve(setDelay(2000))这句代码没有为setDelay加then,导致其成为未定状态(pending),于是setDelay里的resolve未定义,于是直接返回其resolve的参数(`我延迟了${millisecond}毫秒后输出的`),最后resolve(setDelay(2000))就变成了resolve(`我延迟了${millisecond}毫秒后输出的`)

而加了then之后就正常了


  • 1

Reply