我在JavaScript中有一个cpu密集型任务,在Promise
内执行时阻塞了VM:
可以是以下示例(在浏览器中试用):
function task() {
return new Promise((r,s) => {
for(var x=0; x < 1000000*1000000; x++) {
var Y = Math.sqrt(x/2)
}
return r(true)
})
}
我想避免阻止VM主线程,所以我尝试使用setTimeout
中的Promise
分隔resolve
和reject
上下文如:
function task() {
return new Promise((r,s) => {
var self=this;
setTimeout( function(r,s) {
for(var x=0; x < 1000000*1000000; x++) {
var Y = Math.sqrt( Math.sin (x/2) + Math.cos(x/2))
}
return r(true);
},500,r,s);
})
}
但没有成功。知道如何避免主线被卡住吗?
答案 0 :(得分:1)
您可以使用&#34; Web Workers&#34;。这样,你就保持符合标准。这基本上是一个后台线程(例如旧版C#中的BackgroundWorker)。
我不确定当前node.js是否支持这个,所以请使用 npm web workers package
答案 1 :(得分:1)
除了使用Web worker或类似工具之外,您还可以(根据任务)将工作分解为使用setImmediate
处理和计划的较小块。这个例子有点傻,但你明白了。
function brokenUpTask() {
let x = 0; // Keep track of progress here, not in the loop.
const limit = 1000000;
const chunk = 100000;
return new Promise((resolve) => {
function tick() { // Work a single chunk.
let chunkLimit = Math.min(x + chunk, limit);
for(x = 0; x < chunkLimit; x++) {
var Y = Math.sqrt(x/2);
}
if(x === limit) { // All done?
resolve(true);
return;
}
setImmediate(tick); // Still work to do.
}
tick(); // Start work.
});
}
brokenUpTask().then(() => console.log('ok'));