有时我需要等待.forEach()方法完成,主要是在#loader;#功能。这就是我这样做的方式:
cygpath
我无法帮助,但我觉得这不是等待.forEach()完成的最好方法。这样做的最佳方式是什么?
答案 0 :(得分:31)
var foo = [1,2,3,4,5,6,7,8,9,10];
如果你真的在循环中做异步内容,你可以把它包装在一个承诺中......
var bar = new Promise((resolve, reject) => {
foo.forEach((value, index, array) => {
console.log(value);
if (index === array.length -1) resolve();
});
});
bar.then(() => {
console.log('All done!');
});
答案 1 :(得分:10)
board[1][1] = '*'
不是异步的,例如在此代码中:
forEach
array.forEach(function(item){
//iterate on something
});
alert("Foreach DONE !");
完成后,您会看到提醒。
答案 2 :(得分:6)
使用ES6进行这项工作的最快方法就是使用for..of
循环。
const myAsyncLoopFunction = async (array) {
const allAsyncResults = []
for (const item of array) {
const asnycResult = await asyncFunction(item)
allAsyncResults.push(asyncResult)
}
return allAsyncResults
}
或者您可以使用Promise.all()
并行遍历所有这些异步请求,如下所示:
const myAsyncLoopFunction = async (array) {
const promises = array.map(asyncFunction)
await Promise.all(promises)
console.log(`All async tasks complete!`)
}
答案 3 :(得分:5)
如果您在循环中有一个异步任务并且您想等待。您可以使用 for await
for await (const i of images) {
let img = await uploadDoc(i);
};
let x = 10; //this executes after
答案 4 :(得分:1)
在每个可能的唯一代码分支(包括回调)的末尾更改并检查一个计数器。示例:
.searchcontainer {
text-align:center;
width: 100%;
max-width: 600px;
margin: 0 auto;
}
.searchcontainer .search-part {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
mat-form-field.mat-form-field {
font-size: 12px;
width: 300px;
}
button.mat-stroked-button {
font-size: 14px;
height: 42px;
margin: 10px;
}
答案 5 :(得分:1)
用于确保所有forEach()元素完成执行的通用解决方案。
const testArray = [1,2,3,4]
let count = 0
await new Promise( (resolve) => {
testArray.forEach( (num) => {
try {
//some real logic
num = num * 2
} catch (e) {
// error handling
console.log(e)
} fanally {
// most important is here
count += 1
if (count == testArray.length) {
resolve()
}
}
})
})
这个想法与使用索引计数的答案相同。但是在实际情况下,如果发生错误,索引方式将无法正确计数。因此该解决方案更加健壮。
Thx
答案 6 :(得分:0)
forEach()不返回任何内容,因此更好的做法是map()
+ Promise.all()
var arr = [1, 2, 3, 4, 5, 6]
var doublify = (ele) => {
return new Promise((res, rej) => {
setTimeout(() => {
res(ele * 2)
}, Math.random() ); // Math.random returns a random number from 0~1
})
}
var promises = arr.map(async (ele) => {
// do some operation on ele
// ex: var result = await some_async_function_that_return_a_promise(ele)
// In the below I use doublify() to be such an async function
var result = await doublify(ele)
return new Promise((res, rej) => {res(result)})
})
Promise.all(promises)
.then((results) => {
// do what you want on the results
console.log(results)
})
答案 7 :(得分:0)
与其他版本相比,我不确定此版本的效率,但是最近在我的forEach()中具有异步函数时才使用此版本。它不使用promise,映射或for-of循环:
// n'th triangular number recursion (aka factorial addition)
function triangularNumber(n) {
if (n <= 1) {
return n
} else {
return n + triangularNumber(n-1)
}
}
// Example function that waits for each forEach() iteraction to complete
function testFunction() {
// Example array with values 0 to USER_INPUT
var USER_INPUT = 100;
var EXAMPLE_ARRAY = Array.apply(null, {length: USER_INPUT}).map(Number.call, Number) // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, n_final... ] where n_final = USER_INPUT-1
// Actual function used with whatever actual array you have
var arrayLength = EXAMPLE_ARRAY.length
var countMax = triangularNumber(arrayLength);
var counter = 0;
EXAMPLE_ARRAY.forEach(function(entry, index) {
console.log(index+1); // show index for example (which can sometimes return asynchrounous results)
counter += 1;
if (triangularNumber(counter) == countMax) {
// function called after forEach() is complete here
completionFunction();
} else {
// example just to print counting values when max not reached
// else would typically be excluded
console.log("Counter index: "+counter);
console.log("Count value: "+triangularNumber(counter));
console.log("Count max: "+countMax);
}
});
}
testFunction();
function completionFunction() {
console.log("COUNT MAX REACHED");
}
答案 8 :(得分:0)
我不得不处理相同的问题( forEach ,其中使用了多个promise ),而当前提出的解决方案都没有对我有帮助。因此,我实现了一个检查数组,每个诺言都会更新其完整状态。我们有一个概括整个过程的总体承诺。我们仅在每个承诺完成时解决一般承诺。代码段:
function WaitForEachToResolve(fields){
var checked_fields = new Array(fields.length).fill(0);
const reducer = (accumulator, currentValue) => accumulator + currentValue;
return new Promise((resolve, reject) => {
Object.keys(fields).forEach((key, index, array) => {
SomeAsyncFunc(key)
.then((result) => {
// some result post process
checked_fields[index] = 1;
if (checked_fields.reduce(reducer) === checked_fields.length)
resolve();
})
.catch((err) => {
reject(err);
});
}
)}
}
答案 9 :(得分:0)
const array = [1, 2, 3];
const results = [];
let done = 0;
const asyncFunction = (item, callback) =>
setTimeout(() => callback(item * 10), 100 - item * 10);
new Promise((resolve, reject) => {
array.forEach((item) => {
asyncFunction(item, (result) => {
results.push(result);
done++;
if (done === array.length) resolve();
});
});
}).then(() => {
console.log(results); // [30, 20, 10]
});
// or
// promise = new Promise(...);
// ...
// promise.then(...);
“结果”数组中结果的顺序可能与原始数组中项目的顺序不同,具体取决于asyncFunction()完成每个项目的时间。
答案 10 :(得分:0)
您可以使用它,因为我们在 forEach
循环内使用 async/await。您可以在循环内使用自己的逻辑。
let bar = new Promise((resolve, reject) => {
snapshot.forEach(async (doc) => {
"""Write your own custom logic and can use async/await
"""
const result = await something()
resolve(result);
});
});
let test = []
test.push(bar)
let concepts = await Promise.all(test);
console.log(concepts);
答案 11 :(得分:0)
对于简单的比较代码,我喜欢使用 for 语句。
transport not available