如何避免CPU绑定任务阻止JavaScript VM

时间:2018-03-15 13:32:23

标签: javascript node.js cpu-usage

我在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分隔resolvereject上下文如:

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);
   })
}

但没有成功。知道如何避免主线被卡住吗?

2 个答案:

答案 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'));