当我没有使用 `await` 关键字时,节点正在等待一个函数

node is waiting for a function when I'm not using the `await` keyword

据我了解,async 函数是异步的。所以它不会等待,所以调用者不会等待它立即完成 returns 一个将在稍后解决的承诺。除非你使用 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:

这不是我希望发生的事情我希望最后一条消息立即打印,并作为“开始”和“完成”之前的第一条消息。我有什么不明白的?

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()

这样试试

foo() 中的代码完全是阻塞和同步的。它不会 return 直到它里面的代码执行完毕。向函数添加关键字 async 不会改变任何内容。

许多人显然对 async 关键字感到困惑。它很有用(当与 await 和 promise-returning 异步函数结合使用时),但是当您没有使用 promises 的异步代码时根本没有用。

防止这个巨大的 for 循环阻塞的唯一方法是将其移至 WorkerThread 或子进程。它只是同步和阻塞,nodejs 中主线程的单线程性质意味着当 for 循环是 运行ning 时,没有其他东西可以 运行(除非它在 ​​WorkerThread 或子进程)。


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