2017-10-23 7 views
-1

私がしようとしているのは、IDを表す整数の束を持つ配列があるということです。私はIDで配列をループします。各idに対して、私はjsonを返すajax呼び出しを行い、次にこのjsonを結果配列に追加します。私はajax呼び出しを行った同じ順序で結果配列の順序を保持したいと思います(つまり、 '/ url/1'、 'url/2'、url/3 ' 、私が呼び出しが行われた順に番号1、2及び3からの結果を格納する結果アレイたい。ここで私は私が持っているものを表示しなければならない一般的なコードである。複数のajax呼び出しを行った後、Javascriptで配列の順序を維持する

var ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 
var results = []; 
var counter = 1; 
ids.forEach(function(id) { 
    doAjax('GET', 'url' + id, function(returnValue) { 



     results.push(returnValue); 
     if (counter == 10) { 
      //dispatch some event 
     } 

    }); 



}); 

問題は、ということです結果配列の順序は、ajax呼び出しの非同期性のために毎回異なります。すべてのajax呼び出しが行われた後も結果の順序が同じになるようにする方法はありますか(つまり、result = [idの結果1、、...] ID 10に起因ID 3から生じる、ID 2に起因?

+2

'forEach'の方法は、第2のパラメータとしてのアイテムのインデックスをとりコールバックを受け付けます。だから、それを作成したIDと同じインデックスに結果を置くことができますか? IE: 'ids.forEach(function(id、index){結果[インデックス] = returnValue})'。 – CRice

+0

現在の実行コンテキストが完了し、JSランタイムがアイドル状態になるまで、AJAX呼び出し結果は使用できません。これは、成功コールバックが実行されるまでにループが終了することを意味します。 –

答えて

1

約束を使用すると、多くの理由から良い考えであり、作成した順番で結果が得られます。

スタート約束で各AJAX呼び出しをラップすることにより、コールの結果でそれを解決します。そして、あなたは、アレイ内のすべての約束が解決したときに解決し、単一の約束をすることができ、これにコールバックが持つ配列が渡されます

var promises = ids.map(function(id) { 
    return new Promise(function(resolve) { 
    doAjax('GET', 'url' + id, function(returnValue) { 

     resolve(returnValue); 
    }); 
    }); 
}); 

:すべての約束を持つ配列を伝播するmap()の代わりforEach()を使用します正しい順序ですべての結果:

Promise.all(promises).then(function(promiseResults) { 
    // The promiseResults array here will contain the results of all AJAX calls in the order you created them 
}); 

あなたが見ることができるように約束を使用しているとき、あなたはcounterたり宣言しresults変数を必要としません。
これはすべてもっときれいに効率的に書くことができますが、私の例ではあなたがそのアイデアを得るのを助けてくれるでしょう。

2

あなたのdoAjaxpromiseを返し、配列の各要素を約束し、約束の配列をPromise.allに渡します。結果配列Promise.all "returns"は入力配列と同じ順序です。

+0

2つ目の引数を 'then'に追加すると、要求の1つが失敗した場合に備えて何かを行うことができます。 – 4thex

0

あなたは、各idは、このようなオブジェクトであるとする必要があります。id.idを使用し、代わりにdoAjaxにIDを参照の今

var ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(function(id) { 
    return {id: id}; 
}); 

。 代わりに別の配列にあなたの結果をプッシュするので、あなたは、単にこのように、idオブジェクトに新しいプロパティを追加することができます。

id.result = returnValue; 

あなたが好きな場合は、results配列を作成するために別のマップ操作を行うことができます。

var results = ids.map(function(id) { 
    return id.result; 
}); 
関連する問題