【问题标题】:Does await await promise-like objects? [duplicate]是否等待等待类似承诺的对象? [复制]
【发布时间】:2017-07-18 11:21:30
【问题描述】:

根据Mozilla,await 只等待 Promises:

[rv] 返回 promise 的解析值,如果不是 Promise,则返回值本身。

如果你等待一个非 Promise,一个已解决的 Promise 将立即返回,它不会等待。但是,以下代码在 Chrome 和 FF 中不使用 Promises 即可等待。

var obj = {
    then:func => obj.func=func
};
setTimeout(() => obj.func(57), 1000);

async function go() {
    var res = await obj;
    console.log(res); //shows '57' after 1000ms
}

go();

根据规范,应该 await await 不是 Promises 的类似 Promise 的对象吗? (我尝试查看规格(链接自 Mozilla 文章),但我无法理解。)

【问题讨论】:

  • 主要问题是什么是 ES-transpiler/interpretator 的 Promise,它执行 await 操作。例如,你可以使用 bluebird Promise,但默认配置中的 babel 不会理解它。主要定义之一是promise === Promise.resolve(promise),但编译器在编译时看不到它。
  • 实际上它确实使用了 Promise,你只是看不到它们 :-) 顺便说一句,那些“类似 Promise 的对象”也被称为 thenables
  • @Bergi 你链接到的问题不相关,因为那是关于等待数字,而不是thenables。我的问题是:在规范中等待thenables
  • @wezten 答案解释了每个等待值会发生什么,无论是承诺、数字还是 thenable。 Promise.resolve 处理 thenables - 是的,它在规范中。
  • @Bergi 在那个答案中它在哪里谈论thenables?所有答案都显示await obj == await Promise.resolve(obj),但我不知道Promise.resolve(obj) 是否会按原样返回obj 的已解决承诺,或者它是否检测到它具有then 属性,并返回等待的未解决承诺用于调用传递给then 的回调。

标签: javascript asynchronous async-await


【解决方案1】:

await 将触发obj.then(),这就是导致这种行为的原因。因为即使obj 不是Promise,也是一个thenable 对象

你有一些关于here的信息。

在你的情况下它有效,因为:

第一个刻度

  1. obj 已初始化
  2. setTimeout()被执行,它的回调会在下一个tick中被调用
  3. go() 已声明
  4. go() 被执行
  5. awaitgo()内部触发,执行obj.then(),将解析函数分配给obj.func
  6. 还没有解决,所以打勾到这里结束

第二次勾号

  1. 执行setTimeout() 回调,通过obj.func() 解析promise,值为57

第三次滴答

  1. 控制返回go(),结果57被记录

【讨论】:

  • 我写了它,所以我明白它为什么有效。我的问题是,如果 then 不是 Promise 属性,规范中是否说 await 应该检查对象的 then 属性,或者这是浏览器实现的,不在规范中?
【解决方案2】:

来自that same page

如果值不是Promise,它会将值转换为已解析的Promise,并等待它。

该值将因此自动转换为已解析的Promise,然后等待。

【讨论】:

  • 但是在我的示例中,返回了一个未解决的承诺,因为它又等待了 1000 毫秒。如果解决了,它会立即返回。该页面的含义是该参数立即按原样返回,因此在我的示例中它将返回{then:func => obj.func=func},而不是57 - 请参见此处的示例。
猜你喜欢
  • 2013-09-16
  • 2019-12-10
  • 1970-01-01
  • 1970-01-01
  • 2016-07-18
  • 2019-04-29
  • 2020-10-31
  • 2018-02-03
  • 2018-03-05
相关资源
最近更新 更多