JavaScriptのループは同期か非同期か?(for, while, etc)
あるとします。
for(let i=0; i<10; i++){
// A (nested stuff...)
}
// B ...
forを使用すると、
Bの実行が
A` よりも先に開始されることがあります...(つまり非同期)
ステートメントを同期的に使用する方法はありますか?
forループは、すべての非同期処理が開始される間、直ちに完了するまで実行されます。
さて、ここではいくつかのループを入れ子にしています。注目すべきは、"BBB" が常に後に実行されることです。
for(let i=0; i<10; i++){
for(let i=0; i<10; i++){
for(let i=0; i<10; i++){
console.log("AA")
}
}
}
console.log('BBB')
さて、これを見てください。
for(let i=0; i<10; i++){
setTimeout(function() {console.log("AA")}, 2000)
}
console.log('BBB')
これは、"イベントループ"と呼ばれるもののせいです。そして、このsetTimeoutで非同期処理をシミュレートしているという事実です。それは、ajax呼び出しや他の非同期処理かもしれません。
こちらをご覧ください: http://latentflip.com/loupe
これは、この種の非同期/同期ループのトピックを理解するのに非常に役立ちます。
プロミスがどのように動作するかを示すために更新されました(以下のコメントを参照してください)。
var stringValues = ['yeah', 'noooo', 'rush', 'RP'];
var P = function(val, idx){
return new Promise(resolve => setTimeout(() => resolve(val), 1000 * idx));
};
// We now have an array of promises waiting to be resolved.
// The Promise.all basically will resolve once ALL promises are
// resolved. Keep in mind, that if at any time something rejects
// it stops
// we iterator over our stringValues array mapping over the P function,
// passing in the value of our array.
var results = Promise.all(stringValues.map(P));
// once all are resolved, the ".then" now fires. It is here we would do
results.then(data =>
console.log(data) //["yeah", "noooo", "rush", "RP"]
);
もし私が十分に明確でないなら教えてください。
非同期ループを for...loop
の中に配置し、それぞれの処理が終了するまでループを停止させたい場合は、以下のように async/await
シンタックスを使用しなければなりません。
async function foo() {
var array = [/* some data that will be used async*/]
//This loop will wait for each next() to pass the next iteration
for (var i = 0; i < array.length; i++) {
await new Promise(next=> {
someAsyncTask(array[i], function(err, data){
/*.... code here and when you finish...*/
next()
})
})
}
}
foo().then(() => { /*After foo execution*/ })
let items = YourArray;
let i = 0;
await new Promise(async (resolve, reject) => {
try {
if (items.length == 0) return resolve();
let funSync = async () => {
await yourASyncFunctions(items[i].doAnything);
i++;
if (i == items.length) resolve();
else funSync();
}
funSync();
} catch (e) {
reject(e);
}
});