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交换数据等等...
我正在尝试让一个函数调用一些代码,同时让我的主函数继续运行,而不必等待它。
目前还没有成功:
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交换数据等等...