【问题标题】:Why is my infinite loop blocking when it is in an async function? [duplicate]为什么我的无限循环在异步函数中时会阻塞? [复制]
【发布时间】:2021-06-28 10:52:47
【问题描述】:

我不明白如何使用异步函数。

为什么下面的代码会停止主线程?

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

【问题讨论】:

  • 异步代码不代表多线程,代码仍然在一个线程中运行。异步只是某种协作式多任务处理,而不是多线程处理。
  • @Ivar — 现在大多数现代 JS 实现都支持一种线程形式。只是async关键字不是这样的。
  • 浏览器有一个事件循环。当您调用异步函数时,该函数将被安排在下一个循环中运行,但仍然是单线程的。
  • @behzadbesharati 调用 async 函数未安排执行。它将立即执行(如您在此 fiddle 中所见)。返回的 Promise 将在稍后的状态下解析。

标签: javascript asynchronous async-await es6-promise


【解决方案1】:

async 关键字和一般的承诺,不要让同步代码异步,不要让慢速运行代码快速,或者阻塞代码非阻塞。

async 只是让函数返回一个 Promise 并提供(使用 await 关键字)与其他 Promise 交互的机制,就好像它们是同步的一样。

你的函数开始一个循环,然后就一圈又一圈。

它没有到达函数的末尾,这将结束函数并解析它返回的承诺。

它没有到达 await 关键字并在等待等待的承诺得到解决时暂停。

只是转来转去。

如果您实际上是在循环中一些计算量很大的事情,并且您想进入后台,那么您可以使用 Node.js Worker Thread 或基于浏览器的 @ 987654322@去做吧。

【讨论】:

    【解决方案2】:

    async 关键字放在函数前仅表示这是异步函数。您需要在要实际等待的函数之前包含关键字await。就像这样:

    async function hashPin(pin){
        const hashedPin = await bcrypt.hash(pin, saltRounds);
    }
    

    这只是我的一个项目中的示例(在发布之前已经删除了冗余代码)

    【讨论】:

    • 好,这个对我有用。
    • 我不知道为什么这会起作用,因为无限循环仍然会阻塞。
    • async 在函数前面有两个目的。 1. 在函数中启用await。 2. 它告诉调用者保证这个函数返回一个Promise。但是asyncawait 都不能神奇地解决阻塞问题。因此,如果bcrypt.hash 中有一些阻塞代码,那么它前面的await 将无法解决该阻塞问题。删除await 并写入async function hashPin(pin){ return bcrypt.hash(pin, saltRounds).then( hashedPin => /*...*/)} 不会对阻塞产生影响。
    • 你们是对的,我完全错过了关于无限循环的部分,只提供了如何使用异步函数的答案。我的坏
    猜你喜欢
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    相关资源
    最近更新 更多