【问题标题】:Promise.await() vs. Top-Level Await?Promise.await() 与顶级等待?
【发布时间】:2022-09-28 23:25:43
【问题描述】:

这不起作用:

function myFunction(myObject){
    let IM = await connectors.myModel.update({
        myField: true,
    }, {
        where: {id: myObject.id},
        returning: true,
    });
}

但这确实有效:

function myFunction(myObject){
    let IM = Promise.await(connectors.myModel.update({
        myField: true,
    }, {
        where: {id: myObject.id},
        returning: true,
    }));
}

我了解您不能在async function 之外使用awaitPromise.await() 和即将推出的 node.js 功能 Top-Level await 有什么区别?

  • 你的Promise 是什么? vanilla JS中没有Promise.await这样的东西
  • 好问题。我还不知道为什么这段代码有效。 Promise 不是变量——它只是关键字Promise
  • 哦,好吧——一定是因为我的构建工具是 Meteor。我不知道 Meteor 对 Promises 做了什么特别的事情。

标签: node.js meteor async-await promise


【解决方案1】:

Promise.await 接受一组 promise,并在它们全部解析时解析,并在解析时返回结果数组。

顶级 await 让您可以调用 await,就好像您的整个全局代码在异步块中一样。

您的代码有效,因为您没有等待 Promise.await。你应该是,或者打电话给then

如果您想在顶层等待,请将您的代码放在 IIFE 块中。

;(async function() {
  await foo();
})();

【讨论】:

    【解决方案2】:

    Fibers 和 Promise.await

    Meteor 在底层使用fibers(协程,repo here)来支持异步编程。这就是为什么你可以在服务器上编写 Meteor 同步风格的代码,尽管它本质上可能是异步的:

    const doc = MyCollection.findOne()
    doc.someProp // yeay it's there without await
    

    Promise.await 也是如此,它使用当前的光纤作为执行环境。您可以在 Meteor 方法中运行以下代码:

    Meteor.methods({
      test () {
        const someAsyncFn = async () => 'foo'
        const foo = Promise.await(someAsyncFn())
        return foo // 'foo'
      }
    })
    

    顶级等待和本机异步/等待

    现在你很想知道为什么在 2022 年 Meteor 仍然不会使用真正的反异步 async/await。简单地说,它是一个具有 10 年历史的框架,具有高稳定性和向后兼容性。迈向原生 async/await 的步骤需要丢弃纤程,纤程本身已深深嵌入 Meteor 的核心!

    然而,关于转向原生 async/await 的讨论已经导致了它的开发:https://github.com/meteor/meteor/discussions/11505

    随着即将到来的 Meteor 2.8,将会有第一个原生的 async/await 支持。 顶级异步将在此之后可用,is still wip

    我应该怎么办?

    现在你应该从 Meteor 2.8 开始慢慢地将代码重写为 async/await 并尽量避免Promise.await,除非不可能。

    您已经可以编写异步风格的服务器方法,而不会对行为产生太大影响:

    Meteor.methods({
      test: async function () {
        const someAsyncFn = async () => 'foo'
        const foo = await someAsyncFn()
        return foo // 'foo'
      }
    })
    

    现在你不能使用顶级 await 并且需要将它包装在一个 IIFE 块中:

    (async () => {
    
    })()
      .then(res => {})
      .catch(e => {})
    

    【讨论】:

      【解决方案3】:

      看起来这是因为我的构建工具 Meteor 正在用 Promises 做一些很酷的事情。

      【讨论】:

      • “酷”是指“非标准”吗?
      • 似乎我有类似顶级等待的东西并使用了多年。它工作得很好。我希望它是标准的,我猜顶级 await 将在即将发布的 node.js 版本中成为标准。
      猜你喜欢
      • 2021-03-26
      • 1970-01-01
      • 2021-02-13
      • 1970-01-01
      • 2021-03-09
      • 2023-03-05
      • 2022-01-02
      • 2020-12-22
      相关资源
      最近更新 更多