forEach/map 및 async는 함께 사용되지 않습니다.
May 07 2023
때때로 우리는 종종 forEach 및 map 함수와 함께 비동기 함수를 전달하는 경향이 있습니다. 예: 결과: 1부터 모든 숫자.

때때로 우리는 종종 forEach 및 map 함수와 함께 비동기 함수를 전달하는 경향이 있습니다.
예를 들어:
[1,2,3,4,5].forEach(async (n) => setTimeout(console.log(n), 1000));
결과: 1..5의 모든 숫자가 차례로 인쇄되지만각 라인을 인쇄한 후 1초의 간격이 없습니다 .
왜 이런 일이 발생합니까?
이 javascipt 함수를 살펴보십시오.
async function doubleOf(n) {
return n*2;
}
결과: 이것은 실제로 숫자로 확인되는 Promise를 반환합니다.
엄격한 유형을 사용하여 이 함수에 해당하는 TypeScript를 작성하면 상황이 명확해집니다.
다음 코드는 컴파일 되지 않습니다 .
async function doubleOf(n: number): number {
return n*2;
}
올바른 버전은 다음과 같습니다.
async function doubleOf(n: number): Promise<number> {
return n*2;
}
async-await에서 제공하는 구문 설탕에 속지 마십시오. 비동기를 사용하지 않고 순수한 약속을 작성했다면 위의 함수는 다음과 같습니다.
function doubleOf(n) {
return new Promise((resolve) => resolve(n*2));
}
function doubleOf(n: number): Promise<number> {
return new Promise((resolve) => resolve(n*2));
}

doubleOf
숫자를 입력받아 숫자를 반환하는 함수가 있습니다 . 평범한 오래된 자바 스크립트.doubleOfOldWay
숫자를 받아서 숫자로 확인되는 약속을 반환하는 함수가 있습니다 .doubleOfNewWay
숫자를 받아 숫자를 반환하는 것처럼 보이지만 실제로는doubleOfOldWay
함수 처럼 숫자로 확인되는 약속을 반환하는 비동기 함수가 있습니다 .doubleOfOldWay
및doubleOfNewWay
기능은 완전히 동일합니다.- 따라서
doubleOfOldWay
및doubleOfNewWay
함수에서 반환된 값에 대해 곱하기 연산을 실행하려고 하면 결과는 입니다NaN
. 다중 약속을 할 수 없기 때문입니다(확실히!). - 곱하고 :
doubleOfOldWay
_doubleOfNewWay
초기 예제로 돌아가서:
[1,2,3,4,5].forEach(async (n) => setTimeout(console.log(n), 1000));
이 forEach 함수에서 기대하는 것을 구현하는 가장 정확한 방법은 간단한 for 루프를 사용하는 것입니다.
for(const number of [1,2,3,4,5]) {
console.log(number);
await new Promise(resolve => setTimeout(resolve, 1000)); // Sleep for "atleast" 1 second
}
[1,2,3,4,5].map(async (n) => n*2);
(5) [Promise, Promise, Promise, Promise, Promise]
0: Promise {<fulfilled>: 2}
1: Promise {<fulfilled>: 4}
2: Promise {<fulfilled>: 6}
3: Promise {<fulfilled>: 8}
4: Promise {<fulfilled>: 10}
각 숫자의 double 목록을 얻기 위해 우리가 할 수 있는 일은 다음과 같습니다.
await Promise.all([1,2,3,4,5].map(async (n) => n*2));
[2, 4, 6, 8, 10]