.forEach()가 완료될 때까지 기다리는 가장 좋은 방법
때때로 나는 기다릴 필요가 있다..forEach()
주로 '완료' 함수에 대한 메서드입니다.이 방법은 다음과 같습니다.
$q.when(array.forEach(function(item){
//iterate on something
})).then(function(){
//continue with processing
});
이 방법이 다른 사람을 기다리는 최선의 방법은 아니라는 생각이 들지 않을 수 없다..forEach()
완성할 수 있습니다.어떻게 하면 좋을까요?
내부에 비동기 코드가 없는 경우forEach
,forEach
는 비동기적이지 않습니다.예를 들어, 다음의 코드에서는,
array.forEach(function(item){
//iterate on something
});
alert("Foreach DONE !");
다음 시간 후에 경고가 표시됩니다.forEach
끝났습니다.
그렇지 않은 경우(내부에는 비동기적인 것이 있습니다),forEach
약속의 루프:
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!');
});
크레딧 : @rolando-benjamin-vaz-ferreira
ES6를 사용하여 이 작업을 수행하는 가장 빠른 방법은 이 기능을 사용하는 것입니다.for..of
고리.
const myAsyncLoopFunction = async (array) => {
const allAsyncResults = []
for (const item of array) {
const asyncResult = 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!`)
}
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!');
});
루프 내에 비동기 작업이 있어 대기할 경우.사용할 수 있습니다.for await
for await (const i of images) {
let img = await uploadDoc(i);
};
let x = 10; //this executes after
각()은 아무것도 반환하지 않으므로 더 나은 방법은 다음과 같습니다.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)
})
사용하다for of
대신forEach
. 이렇게.
for (const item of array) {
//do something
}
console.log("finished");
"finished
"는 루프가 종료된 후에 기록됩니다.
모든 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()
}
}
})
})
이 생각은 인덱스를 사용하여 계산하는 답변과 동일합니다.그러나 실제로 오류가 발생하면 인덱스 방식이 올바르게 계산되지 않습니다.따라서 솔루션이 더욱 강력해집니다.
고마워
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(...);
결과 배열의 결과 순서는 비동기 기능()이 각 항목에 대해 종료된 시간에 따라 원래 배열의 항목 순서와 다를 수 있습니다.
콜백을 포함하여 가능한 모든 고유 코드 브랜치 끝에 있는 카운터를 변경 및 체크합니다.예:
const fs = require('fs');
/**
* @description Delete files older than 1 day
* @param {String} directory - The directory to purge
* @return {Promise}
*/
async function purgeFiles(directory) {
const maxAge = 24*3600000;
const now = Date.now();
const cutoff = now-maxAge;
let filesPurged = 0;
let filesProcessed = 0;
let purgedSize = 0;
await new Promise( (resolve, reject) => {
fs.readdir(directory, (err, files) => {
if (err) {
return reject(err);
}
if (!files.length) {
return resolve();
}
files.forEach( file => {
const path = `${directory}/${file}`;
fs.stat(path, (err, stats)=> {
if (err) {
console.log(err);
if (++filesProcessed === files.length) resolve();
}
else if (stats.isFile() && stats.birthtimeMs < cutoff) {
const ageSeconds = parseInt((now-stats.birthtimeMs)/1000);
fs.unlink(path, error => {
if (error) {
console.log(`Deleting file failed: ${path} ${error}`);
}
else {
++filesPurged;
purgedSize += stats.size;
console.log(`Deleted file with age ${ageSeconds} seconds: ${path}`);
}
if (++filesProcessed === files.length) resolve();
});
}
else if (++filesProcessed === files.length) resolve();
});
});
});
});
console.log(JSON.stringify({
directory,
filesProcessed,
filesPurged,
purgedSize,
}));
}
// !!DANGER!! Change this line! (intentional syntax error in ,')
const directory = ,'/tmp'; // !!DANGER!! Changeme
purgeFiles(directory).catch(error=>console.log(error));
다른 버전에 비해 이 버전의 효율성은 잘 모르겠지만 최근 ForEach()에 비동기 함수가 있을 때 사용했습니다.약속, 매핑 또는 for-of-loop은 사용하지 않습니다.
// 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");
}
저는 같은 문제에 대처해야 했습니다(각각 내부에서 여러 약속을 사용). 현재 제시된 해결 방법은 모두 저에게 도움이 되지 않았습니다.그래서 체크 어레이를 구현했습니다.각 약속의 상태가 모두 갱신되고 있습니까?우리는 그 과정을 마무리 짓는 일반적인 약속이 있다.우리는 각각의 약속이 완료되었을 때에만 일반적인 약속을 해결합니다.코드 조각:
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);
});
}
)}
}
.then() 구문 대신 async-ait를 사용하고 싶기 때문에 데이터의 비동기 처리를 위해 @Ronaldo의 답변을 다음과 같이 수정했습니다.
let finalData = [];
var bar = new Promise(resolve => {
foo.forEach((value, index) => {
const dataToGet = await abcService.getXyzData(value);
finalData[index].someKey = dataToGet.thatOtherKey;
// any other processing here
if (finalData[dataToGet.length - 1].someKey) resolve();
});
});
await Promise.all([bar]);
console.log(`finalData: ${finalData}`);
메모: 조건을 충족시키겠다는 약속이 해결되는 if 조건을 수정했습니다. 당신의 경우에도 똑같이 할 수 있습니다.
비동기/라고 기능을 사용하고 할 수 .이거는 비동기/대기 기능을 사용하고 있기 때문입니다.forEach
루프 안에서 당신만의 논리를 사용할 수 있어요
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);
간단한 비교 코드를 위해 문장으로 사용하는 것이 좋습니다.
doit();
function doit() {
for (var i = 0; i < $('span').length; i++) {
console.log(i,$('span').eq(i).text() );
if ( $('span').eq(i).text() == "Share a link to this question" ) { // span number 59
return;
}
}
alert('never execute');
}
에 for
을 사용하다
await players.reduce(async (a, player) => {
// Wait for the previous item to finish processing
await a;
// Process this item
await givePrizeToPlayer(player);
}, Promise.resolve());
https://gist.github.com/joeytwiddle/37d2085425c049629b80956d3c618971 를 참조해 주세요.
잘 .forEach()
//count
var expecting = myArray.length;
myArray.forEach(function(item){
//do logic here
var item = item
//when iteration done
if (--expecting === 0) {
console.log('all done!');
}
})
언급URL : https://stackoverflow.com/questions/38406920/best-way-to-wait-for-foreach-to-complete
'programing' 카테고리의 다른 글
가상화 리스트:업데이트 속도가 느린 목록이 많습니다. (0) | 2023.02.23 |
---|---|
Angular에서의 $modal 조롱JS 유닛 테스트 (0) | 2023.02.23 |
특정 국가의 Chrome에서 word press err_connection_reset을 누릅니다. (0) | 2023.02.23 |
react에서 .eslintcache 파일을 삭제하는 방법 (0) | 2023.02.23 |
Oracle에서 상위 100개 행을 선택하는 방법 (0) | 2023.02.23 |