这里是不使用包装回调
创建的会递归处理所有东西的功能答案。
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
// ...
});
编辑:更多的解释
我们想要做的改变您必须为一个循环,处理异步函数调用的循环是什么。
目的是要求一个getArray
调用你的stuffs
阵列的索引。
处理完一个索引后,该函数会再次调用自身来处理下一个索引,直到所有对象都得到处理。
-> Treat index 0 -> Treat index 1 -> Treat index 2 -> Return all result
我们正在使用参数传递过程中的信息。 Index
知道我们必须对待哪个阵列部分,并且保留我们计算的一小部分。
编辑:提高到100%异步soluce
我们在这里做了它的初始for循环的一个简单的换位成异步代码。它可以通过完全异步进行改进,这使它更好,但稍微困难一些。
例如:
// 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.all'。 (同意异步真棒!) –
它和瀑布一样,它有什么不好? – Lazyexpert
我同意@GrégoryNEUT,在处理异步代码时应避免循环。 –