NodeJS:异步函数仍然停止主函数

NodeJS: Async function still halts main function

我正在尝试让一个函数调用一些代码,同时让我的主函数继续运行,而不必等待它。

目前还没有成功:

function doSomething() {
  return new Promise((resolve, reject) => {
    if(1) {
        console.log("doing something");
        for(let i = 0; i < 10000; i++) {
            for(let j = 0; j < 10000; j++) {
                for(let k = 0; k < 100; k++) {
                 // Do something for a long time to check if async is working
                }
            }
        }
        console.log("finished doing something");
        resolve( {"dummydata": 10} );
    }
    else {
        reject("error!");
    }
  })
}

function main() {
    doSomething()
    .then(data => console.log(data))
    .catch(err => console.error(err))

    console.log("this should print before doSomething() is finished");
}

main();

这是输出:

doing something

finished doing something

this should print before doSomething() is finished

{ dummydata: 10 }

为什么我的程序在等待 doSomething()?我希望它 运行 并行/异步。我也试过让 main() 成为一个异步函数,与 doSomething() 一样,但那没有用。

JavaScript 仍然是 single-threaded。如果你有一个昂贵的代码段,比如你的嵌套循环,并且你没有 await 在循环中,那么你的环境中的所有其他 JavaScript 处理将在循环迭代时被阻塞 - 控制流将只有在所有同步代码完成后才返回。

立即将代码放在 Promise 构造函数回调的顶层 运行 - 执行 return new Promise 不会将代码放在单独的线程或类似的东西上。

虽然您可以排队任务以便它在延迟后启动,并让主脚本继续它需要做的事情:

function main() {
  setTimeout(doSomething, 2000);
  // more code

要真正运行它并行,你需要使用child_process. Put the expensive section of the script into its own file, and have child_process invoke it via .fork

您可以使用worker_threads:https://nodejs.org/api/worker_threads.html#worker-threads

const { Worker } = require("worker_threads");

const worker = new Worker(
  `
const { parentPort } = require('worker_threads');

parentPort.postMessage("doing something");
  for (let i = 0; i < 10000; i++) {
    for (let j = 0; j < 10000; j++) {
      for (let k = 0; k < 100; k++) {
        // Do something for a long time to check if async is working
      }
    }
  }
  parentPort.postMessage("finished doing something");
  parentPort.postMessage({ dummydata: 10 });

`,
  { eval: true }
);
worker.on("message", (message) => console.log(message));

console.log("this should print before doSomething() is finished");

这只是一个片段。可以和worker交换数据等等...