等待非 Promise 是不是有任何可检测的效果?

Posted

技术标签:

【中文标题】等待非 Promise 是不是有任何可检测的效果?【英文标题】:Does awaiting a non-Promise have any detectable effect?等待非 Promise 是否有任何可检测的效果? 【发布时间】:2019-08-11 06:41:27 【问题描述】:

可以await 一个非承诺和that's good so。

所有这些表达式都是有效的并且不会导致错误:

await 5
await 'A'
await 
await null
await undefined 

等待非 Promise 是否有任何可检测的影响?为了避免潜在的错误,人们应该注意哪些行为差异?任何性能差异?

以下两行是完全相同还是理论上不同?:

var x = 5
var x = await 5

怎么样?有什么例子可以证明差异吗?

PS:根据TypeScript authors,有区别:

var x = await 5;var x = 5;不一样; var x = await 5; 将在下一个学期分配 x 5,而 var x = 5; 将立即评估。

【问题讨论】:

【参考方案1】:

await 不是空操作。如果等待的东西不是一个承诺,它被包裹在一个承诺中,那个承诺是等待的。因此await 改变了执行顺序(但你不应该依赖它):

console.log(1);
(async function() 
  var x = await 5; // remove await to see 1,3,2
  console.log(3);
)();
console.log(2);

此外,await 不仅适用于 instanceof Promises,而且适用于具有 .then 方法的每个对象:

await  then(cb)  /* nowhere */  ;
console.log("will never happen");

等待非 Promise 是否有任何可检测的影响?

当然,如果 .then 存在于等待的事物上,它就会被调用。

为了避免潜在的错误,应该注意哪些行为差异?

如果您不希望它成为 Promise,请不要将方法命名为“then”。

任何性能差异?

当然,如果您等待某些事情,您将始终将继续推迟到微任务。但一如既往:您可能不会注意到它(作为人类观察结果)。

【讨论】:

no a no op 是什么意思?你的意思是not a no-op 对吗? @kunal 是的,我打字比键盘反应快,导致一些有趣的错别字:) “但你还是不要依赖它” 为什么不呢? @aBetterOliver 示例:您启动了两个运行时间很短的操作并希望使用它们的结果。您知道动作 1 比动作 2 更早结束,因此您将 1 的结果存储在一个变量中,并在 2 完成时访问它。现在有人在某个时候改变了算法,所以 1 比 2 慢。你的代码坏了,没有人知道为什么。如果你必须按特定顺序执行异步任务,你应该明确地写下来。【参考方案2】:

完全同意乔纳斯的说法。他的问题中没有回答的一件事是以下两行是完全相同还是理论上不同?:

以下两行并不完全相同,理论上是不同的。

    变量 x = 5 var x = 等待 5

我的控制台中第一条和第二条语句的执行时间分别为 0.008056640625ms0.055908203125msasync/await、setTimeOut 等是运行 JavaScript Run time 的 Run time 提供的 API。 将 await 置于非承诺将在 event-loop 中执行。第 1 行将在到达stack 后立即执行,但第 2 行将花费一些时间(毫秒),因为它会在跳过 webAPI 等待部分后第一次转到stack,然后到task queue,因为没有承诺得到解决并最终将控制权再次交给stack以执行。

【讨论】:

我认为这个问题已经用示例代码 sn-p 回答了。还是谢谢你! 实际上缺少问题的最后一部分,即 以下两行是完全相同还是理论上不同? @JonasWilms 的示例代码非常清楚地显示了差异...... 太棒了。然后假设它是另一种解释:)

以上是关于等待非 Promise 是不是有任何可检测的效果?的主要内容,如果未能解决你的问题,请参考以下文章

非 Promise 值的“等待”无效(Bluebird 承诺)

从异步等待函数中获取 Bluebird Promise

检测 iframe src 是不是可显示

这一次,彻底弄懂 Promise 原理

Promise.all() 不等待异步进程

TS2570 错误协助:“Promise<User>”类型上不存在属性“sendEmailVerification”。您是不是忘记使用“等待”?