【问题标题】:Implicit `resolve` in JavaScript promisesJavaScript Promise 中的隐式`resolve`
【发布时间】:2020-07-31 11:25:07
【问题描述】:

我在 JavaScript 中使用 setTimeout 的 Promise,我得到了一些神秘的行为。我看到一切正常,但我无法解释。

假设我有这个功能:

function f(callback) {
  setTimeout(() => callback(13), 3000);
}

当我在没有回调的情况下调用它时,我得到了一个最预期的错误:

> f()
undefined
> Uncaught TypeError: callback is not a function

当我使用实际回调调用它时,一切正常:

> f(console.log)
undefined
> 13

«问题»

到目前为止,一切都按计划进行,但是当我调用 f() 时,它似乎不再需要 callback 参数:

> new Promise(f).then(console.log)
Promise { <pending> }
> 13

稍微慢一点,如果我存储承诺,它最终会得到一个值:

> p = new Promise(f)
Promise { <pending> }
> p
Promise { <pending> }
> p // after 3 seconds
Promise { 13 }
>

这发生在浏览器和节点上。

问题:f 怎么可能不抱怨缺少callback?值 13 是如何分配为承诺值的?

TL;DR === false我知道我应该算上我的祝福,因为它正在工作,但文档似乎没有提到我可以找到的任何隐藏的默认机制来处理这种情况。我得到的只是一个简短的介绍,然后是快速进入链接和更高级模式的路径。我需要确保我可以在更复杂的情况下复制这种行为。

【问题讨论】:

  • 回调由 resolve 方法解析 - 如果您将指向方法的指针传递给 new Promise 它将收到 2 个参数 - 解析和拒绝。尝试console.log(arguments)f函数内

标签: javascript node.js settimeout es6-promise


【解决方案1】:

让我们把 f 移到 Promise 构造函数中……

new Promise(function f(callback) {
  setTimeout(() => callback(13), 3000);
}).then(console.log)

然后让我们添加另一个参数...

new Promise(function f(callback, reject) {
  setTimeout(() => callback(13), 3000);
}).then(console.log)

并重命名回调来解决:

new Promise(function f(resolve, reject) {
  setTimeout(() => resolve(13), 3000);
}).then(console.log)

是不是很眼熟?

【讨论】:

    【解决方案2】:

    f 怎么可能根本不抱怨缺少回调?

    你为 promise 提供的函数确实接收参数:resolvereject 回调。

    promise 的正常使用如下所示:

    return new Promise((resolve, reject) => {
      // call resolve() on success
      // call reject() on error
    });
    

    如何将值 13 分配为承诺值?

    当您的超时到期时,您正在调用resolve(13)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-17
      • 2019-12-14
      • 2019-01-20
      • 2021-11-05
      • 1970-01-01
      • 2019-06-20
      • 2020-05-30
      相关资源
      最近更新 更多