2017-07-21 11 views
0

は、例えば、この機能を取る:setIntervalのコールバックが指定された間隔で正確に呼び出されるようにするにはどうすればよいですか?

function mySlowFunction(baseNumber) { 
    console.time('mySlowFunction'); 
    var result = 0; 
    for (var i = Math.pow(baseNumber, 10); i >= 0; i--) {  
     result += Math.atan(i) * Math.tan(i); 
    }; 
    console.timeEnd('mySlowFunction'); 
    return result; 
} 

これは非常にCPU集中型の関数です。 mySlowFunction(5)の完了には約3秒かかります。

今、このコードを考えてみましょう。

setInterval(() => console.log("interval"), 1000); 
mySlowFunction(5); 

私はそれがログインするために期待する「インターバル」毎秒、私はmySlowFunctionがスレッド上で実行されていて、JSはシングルスレッドであるため、setIntervalのコールバックがあることを理解mySlowFunctionが完了した後にのみ実行されます。

コールバックが指定された間隔で呼び出されるようにする方法はありますか?私はブラウザベースの環境でこれを望みます。

+1

あなたは単に数秒間何もしてメインスレッドをブロックするべきではありません。集中的な計算が必要な場合は、それらをWebワーカーに配置するか、 'setTimeout'を使用して割り込み可能なチャンクに分割してください。 – deceze

+0

私はあなたがそれを確信できるとは思っていません、あなたが言ったのはまさにその理由です:JSはシングルスレッドです。私はこれの周りに道があるとは思わない。 –

答えて

1

指定した遅延でインターバルが発生するとは限りません。
Here -> (Reasons for delays longer than specified)は、遅延が予想よりも長くかかる理由がいくつかあります。とにかく、あなたはまだあなたにコメントで述べたことができますmySlowFunction完成し、実行は、WebワーカーAPIの労働者インタフェースをすることができ、バックグラウンドタスクを表しWorker

を使用する前に、あなたの間隔が発動するようにしたい場合簡単に作成でき、作成者にメッセージを送り返すことができます。

mySlowFunctionの計算を別のスレッドに割り当てる。ここで

は一例です:

var blobWorker = URL.createObjectURL(new Blob([ '(', 
 
    function() { 
 
     self.onmessage = function(e) { 
 
      
 
     \t var result = 0; 
 
     \t for (var i = Math.pow(e.data, 10); i >= 0; i--) { 
 
      result += Math.atan(i) * Math.tan(i); 
 
     \t }; 
 
     \t 
 
      self.postMessage(result); 
 
     }; 
 
    }.toString(), 
 
')()' ], { type: 'application/javascript' })); 
 

 
var worker = new Worker(blobWorker); 
 

 
worker.onmessage = function(e) { 
 

 
    console.log("result from mySlowWorker:", e.data); 
 
} 
 

 
var intervalId = setInterval(() => console.log("interval"), 1000); 
 

 
worker.postMessage(5); 
 

 
URL.revokeObjectURL(blobWorker); 
 

 
setTimeout(_ => { clearInterval(intervalId); console.log('done') }, 5000)

0

Javascriptではタイマーの遅延は保証されません。タイマーやマウスクリックなどの非同期イベントは、Javascriptの単一スレッドの性質のため、一度に1つずつ実行されます。

関連する問題