문제점: 정신차려보니 끝없이 async await를 쓰고 있다. 중첩된 async await를 어떻게 해결할 것인가.
스택오버플로우에서 유명한 질문을 하나 찾았다.
질문: forEach로 async await를 호출해보니 작동은 하지만 왠지 수상쩍어보여 이렇게 써도 되냐고 물어봄
import fs from 'fs-promise'
async function printFiles () {
const files = await getFilePaths() // Assume this works fine
files.forEach(async (file) => {
const contents = await fs.readFile(file, 'utf8')
console.log(contents)
})
}
printFiles()
답변: 당연 작동은 함. 그치만 printFiles가 비동기 여러개 날려버리고 바로 리턴함.
#1 순서대로 비동기 처리 - for ... of ...
async function printFiles () {
const files = await getFilePaths();
for (const file of files) {
const contents = await fs.readFile(file, 'utf8');
console.log(contents);
}
}
+ for... of... 를 설명하는 16년 댓글: 바벨은 async/await를 generator 함수로 변환하는데, forEach를 쓰면 각각의 이터레이션이 (각자 독고다이 하는) 개별 generator 함수를 갖게 된다. next( ) 컨텍스트 X.
#1 - 2 reduce
async function printFiles () {
const files = await getFilePaths();
await files.reduce(async (promise, file) => {
// This line will wait for the last async function to finish.
// The first iteration uses an already resolved Promise
// so, it will immediately continue.
await promise;
const contents = await fs.readFile(file, 'utf8');
console.log(contents);
}, Promise.resolve());
}
- map은 순서를 보장하지 않으므로 reduce를 사용
#2 동시다발적으로 비동기 처리 - Promise.all( )
async function printFiles () {
const files = await getFilePaths();
await Promise.all(files.map(async (file) => {
const contents = await fs.readFile(file, 'utf8')
console.log(contents)
}));
}
- 매개변수로 배열을 받는 Promise.all 안에 배열을 매핑하는 이유가 새 배열을 반환하기 때문이였음 (이제 깨달음...)
- 같은 이유로 forEach는 안됨. 리턴값을 기다리지 않기 때문
#+ ES2018
async function printFiles () {
const files = await getFilePaths()
for await (const contents of files.map(file => fs.readFile(file, 'utf8'))) {
console.log(contents)
}
}
ES2018으로는 이러한 방식도 가능하다고 함
stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop
www.pluralsight.com/guides/handling-nested-promises-using-asyncawait-in-react
'JS' 카테고리의 다른 글
Class: constructor에서 async await (0) | 2021.03.08 |
---|---|
배열 Array: 루프 (0) | 2021.03.08 |
Fetch API (0) | 2021.03.05 |
Array-like objects, NodeList, HTMLCollection (0) | 2021.03.04 |
배열 Array: 아이템 추가 및 삭제, flat( ) (0) | 2021.03.03 |
댓글