关于promise的一道面试题

Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .then(console.log)

运行结果:

   1

解释:.then 或者 .catch 的参数期望是函数,传入非函数则会发生值穿透。

Promise.resolve(1)
  .then(function(){return 2})
  .then(Promise.resolve(3))
  .then(console.log)

结果为2

Promise.resolve(1)
  .then(function(){return 2})
  .then(function(){return Promise.resolve(3)})
  .then(console.log)

结果为3

不是太明白,then里面必须通过函数来返回的一个值才能被包装为Promise吗?

阅读 7.2k
4 个回答

Promise方法链通过return传值,没有return就只是相互独立的任务而已

Promise在ES6之前其实是个非标准协议,据说最早1976年就有人提出,强调的是Future的状态。在将来如果满足了特定的条件做什么动作(onFulfilled),不满足做什么动作(onRejected)。promise.then(onFulfilled, onRejected)。这样可能稍微好理解一点。回到你的问题

then里面必须通过函数来返回的一个值才能被包装为Promise吗?

你这个问题问的方式就不太对,then只是约定接受一个function作为它的参数,这个function返回什么,它并不关心,你可以不返回,只要promise满足你的特点条件,就会回调你的then。当然,你的then又约定了下一个then的满足条件。只要过程不出错,return之后或者程序执行完就会回调下一个then的onFulfilled,return的结果作为下一个onFulfilled的参数。
好拗口。建议你看看Promise的原理。

Promise.resolve(1)没什么实用价值。
Promise主要是解决异步callback写法不合适的问题,then里面的函数就是callback的函数,比如ajax的回掉函数。

参考MDN这段话:https://developer.mozilla.org...

  • 如果then中的回调函数返回一个值,那么then返回的Promise将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。

  • 如果then中的回调函数抛出一个错误,那么then返回的Promise将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。

  • 如果then中的回调函数返回一个已经是接受状态的Promise,那么then返回的Promise也会成为接受状态,并且将那个Promise的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。

  • 如果then中的回调函数返回一个已经是拒绝状态的Promise,那么then返回的Promise也会成为拒绝状态,并且将那个Promise的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。

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

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题