は、コールバック
すべて詰め込むの治療再帰的つもりだ関数を作成を使用してパッケージのない答えです。
getArray(stuffs, callback, index = 0, array = []) {
// Did we treat all stuffs?
if (stuffs.length >= index) {
return callback(array);
}
// Treat one stuff
if (condition) {
array.add(stuffs[index]);
// Call next
return getArray(stuffs, callback, index + 1, array);
}
// Get a stuff asynchronously
return api.compute(stuffs[index], (resp) => {
array.add(resp.stuff);
// Call next
return getArray(stuffs, callback, index + 1, array);
});
}
どのようにそれを呼び出すには?
getArray(stuffs, (array) => {
// Here you have your array
// ...
});
EDIT:より詳細な説明
私たちは、あなたが非同期関数呼び出しを処理ループに持っていたループを変換するために何をしたいのか。
getArray
のコールは、stuffs
配列の1つのインデックスを処理することを目的としています。
1つのインデックスを処理した後、関数はすべてが処理されるまで、次のインデックスを処理するために自身を再度呼び出します。
-> Treat index 0 -> Treat index 1 -> Treat index 2 -> Return all result
私たちは、プロセスを通じて情報を渡すためにパラメータを使用しています。 Index
私たちが処理しなければならない配列部分を知るために、そしてarray
は、私たちが計算したものを維持するために使用します。
EDIT:改善への100%非同期soluce我々がここで行っている、それは非同期コードにループのためのあなたの初期のシンプルな転置何
。それはそれを完全に非同期にすることによって改善することができますが、それはより良いが少し難しくなります。例えば
:
// Where we store the results
const array = [];
const calculationIsDone = (array) => {
// Here our calculation is done
// ---
};
// Function that's gonna aggregate the results coming asynchronously
// When we did gather all results, we call a function
const gatherCalculResult = (newResult) => {
array.push(newResult);
if (array.length === stuffs.length) {
callback(array);
}
};
// Function that makes the calculation for one stuff
const makeCalculation = (oneStuff) => {
if (condition) {
return gatherCalculResult(oneStuff);
}
// Get a stuff asynchronously
return api.compute(oneStuff, (resp) => {
gatherCalculResult(resp.stuff);
});
};
// We trigger all calculation
stuffs.forEach(x => x.makeCalculation(x));
これはループに非同期コードを置くために悪い習慣です。むしろpromiseの配列を作成し、次にそれらの 'Promise.all'を作成するべきです。 (非同期が素晴らしいことに同意してください!) –
それは滝と同じですが、それには何が悪いですか? – Lazyexpert
私は@GrégoryNEUTに同意します。非同期コードで作業するときはループを避けるべきです。 –