【问题标题】:node is waiting for a function when I'm not using the `await` keyword当我不使用`await`关键字时,节点正在等待一个函数
【发布时间】:2021-12-31 13:33:46
【问题描述】:

据我了解,async 函数是异步的。所以它不会等待所以调用者不会等待它完成它只是立即返回一个将在稍后解决的承诺。除非您使用 await 关键字。

我在 nodejs 中运行这段代码,结果出乎意料

async function foo() {
  console.log('start')
  let sum = 0;
  for(let i = 0; i < 1000000000; i++) {
    sum += 0.00001 * i;
  }
  console.log('finish')
  return sum;
}


function main() {
  foo()
  console.log('this should run immediately:')
}
main()

这是我得到的结果

start
finish
this should run immediately:

这不是我期望发生的,我希望最后一条消息立即打印出来,并作为“开始”和“结束”之前的第一条消息。我不明白什么?

【问题讨论】:

  • “我希望最后一条消息立即打印” - 您希望最后一条console.log 语句在之前执行 foo 函数返回? async 函数同步执行直到遇到第一个await 语句。

标签: node.js asynchronous async-await


【解决方案1】:

foo() 内部的代码完全是阻塞和同步的。在其内部的代码执行完毕之前,它不会返回。在函数中添加关键字 async 并不会改变这一切。

很多人显然对async 关键字感到困惑。它很有用(当与 await 和返回 promise 的异步函数结合使用时),但当您没有使用 promise 的异步代码时则完全没有用处。

防止这个巨大的for 循环阻塞的唯一方法是将它移动到一个 WorkerThread 或一个子进程。它只是同步和阻塞的,nodejs 中主线程的单线程特性意味着当 for 循环运行时,其他任何东西都不能运行(除非它在 ​​WorkerThread 或子进程中)。


您可以使用 setTimeout() 将循环的执行“推迟”到稍后的某个时间,但是当它运行时,它仍然是阻塞和同步的。

【讨论】:

  • 这对我来说是一些新的见解。因此,即使我在 for 循环中使用了诸如 setTimeout 之类的异步方法; conosle.log('start') 是否仍然总是发生在 console.log('this should run immediately:') 之前。根据你所说的,我假设是这种情况。该函数仍将同步运行所有代码,直到遇到异步。所以console.log('start') 会记录它,然后它会运行setTimeout 退出函数,然后是最后一个console.log('finish')。最后是console.log('this should run immediately:')。这是正确的吗?
  • @MrBrN197 - setTimeout() 也是非阻塞的。它只是执行并安排某些东西在将来运行,然后立即返回。我不太理解您在评论中提出的其他问题 - 必须查看代码示例才能知道这意味着什么。
  • 嗨。不用担心,我已经确认了我在说什么。我只是说我的代码中的console.log('start') 仍将在 for 循环之前运行,即使我使用异步代码推迟 for 循环来推迟 for 循环。你的回答很完美,谢谢
【解决方案2】:
async function foo() {
  return new Promise((resolve, reject)=>{
    setTimeout(()=>{
            console.log('start')
            let sum = 0;
            for(let i = 0; i < 100000; i++) {
            sum += 0.00001 * i;
            }
            console.log('finish')
            resolve(sum);
    }, 0)
  })

}


function main() {
  foo()
  console.log('this should run immediately:')
}
main()

这样试试

【讨论】:

    猜你喜欢
    • 2022-01-20
    • 1970-01-01
    • 2021-04-05
    • 2016-08-15
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    • 2020-01-22
    相关资源
    最近更新 更多