2017-08-03 17 views
0

私はJavascriptで実行されるタスクのキューを持っていますが、いくつかはajax呼び出しであり、いくつかは単純なDOMの変更であるため、ターンを待つ。ループを非同期コードで実行しても正しい順序で実行します。

したがって、たとえば、この現象が発生する必要が想像:

Task 1: Takes 1s to complete 
Task 2: Takes 0.5s to complete 
Task 3: Takes 0.3s to complete 
Task 4: Takes 0.75s to complete 

タスク1が(1S)完了するまでタスク2を実行してはならない、など

私は、foreachループを使用して試してみましたコールバックを使用して実行されますが、キューの最後にある場合でも、遅いタスクの前に実行される高速なタスクがあります。それは実際にそれを示すフィドルです。

https://jsfiddle.net/omp5cdm1/

var someArray = [1000, 500, 300, 750]; 
 

 
someArray.forEach(function(item, i) { 
 
    asyncFunc(item, function(item) { 
 
     console.log(i) 
 
    }); 
 
}); 
 

 

 
function asyncFunc(item, callback) { 
 
\t setTimeout(function() { 
 
     document.getElementById("output").innerHTML += item + ', '; 
 
     callback(); 
 
    }, item); 
 
}
Needed output: 1000, 500, 300, 750 
 
<br> 
 
<div id="output">Actual output: 
 

 
</div>

必要な出力順序:1000、500、300、750

実際の出力順序:300、500、750、1000年

編集:私はIE10 +でも動作させる必要があるので、es6を使うことはできません:(

+0

彼らは「順番に」実行する必要のある感覚を明確に:自身が連続して実行する必要がコールバック関数は、連続して実行する必要がありますか、または非同期機能していますか? –

+0

タスクはdomに変更を加え、それらはすべて相互にリンクされているので、厳密に連続して実行する必要があるので、最初のタスクが完了するまでに10秒かかると仮定すると、次のタスク(配列の2番目)最初のものは完了しています(10秒後)。私はこれがもっと理にかなってほしいと思う! – Sometip

+0

setIntervalを使用して前のタスクの継続チェックが完了してから新しいタスクを開始します –

答えて

2

あなたの 'asyncFunc'は実際には非同期ではありません:someArrayの各アイテムに対して直ちに呼び出され、スリープソートのように動作しています。
この例では、配列内の次の項目で関数を呼び出す前にタイムアウトを待ちます。

var arr = [1000, 500, 300, 750]; 
 

 
function next() { 
 
    var item = arr.shift(); 
 
    if (typeof item === 'undefined') return; 
 
    document.getElementById("output").innerHTML += item + ', '; 
 
    asyncFunc(item, next); 
 
} 
 
function asyncFunc(item, callback) { 
 
    setTimeout(callback, item); 
 
} 
 
next();
<div id="output"></div>

+0

async.jsのasync.seriesを使って、これをどのように行うことができるかを示すのも良い考えです – slebetman

関連する問題