async/await
- "비동기로 돌아가는 코드를 동기적으로" 작동하게끔 하는 기능을 한다.
- async 함수 내에서 await 키워드를 작동시키면 "원래는 비동기적으로 일어나야 하는 일이 기다려진다" 라고 생각할 수 있다.
Promise.all
const fs = require("fs");
const util = require("util");
const {
getBodyFromGetRequestPromise,
getDataFromFilePromise
} = require("../exercises/02_promiseConstructor");
const writeFilePromise = util.promisify(fs.writeFile);
const BASE_URL = "https://koreanjson.com/users/";
const fetchUsersAndWriteToFileAsync = async (readFilePath, writeFilePath) => {
const dataList = await getDataFromFilePromise(readFilePath); // [1,2,3,4,5]
let responseDataList;
const responseDataListFunc = async () => {
return await dataList.map(async reqData => {
return await getBodyFromGetRequestPromise(BASE_URL + id);
// 여기서 await getBodyFromGetRequestPromise(BASE_URL + id)를 콘솔에찍으면 결과값이 잘나온다
});
};
responseDataList = responseDataListFunc();
console.log("responseDataList ? ", responseDataList);
};
module.exports = {
fetchUsersAndWriteToFileAsync
};
문제가 있었던 코드는 아래의 코드..!
const fetchUsersAndWriteToFileAsync = async (readFilePath, writeFilePath) => {
const dataList = await getDataFromFilePromise(readFilePath); // [1,2,3,4,5]
let responseDataList;
const responseDataListFunc = async () => {
return await dataList.map(async reqData => {
return await getBodyFromGetRequestPromise(BASE_URL + id);
});
};
responseDataList = responseDataListFunc();
console.log("responseDataList ? ", responseDataList);
};
map 메소드를 통해 각각의 url에서 응답받은 데이터로 dataList
를 매핑하려했지만.. 콘솔에 찍힌 결과값은... 아래와 같다.
const responseDataListFunc = async () => {
let result = await dataList.map(async id => {
return await getBodyFromGetRequestPromise(BASE_URL + id);
});
console.log("result ? ", result);
};
이렇게 map의 결과값을 result에 담아 콘솔에 찍어보면 아래와같이 promise 대기 상태가 찍힌다
const responseDataListFunc = async () => {
await dataList.map(async id => {
let result = await getBodyFromGetRequestPromise(BASE_URL + id);
console.log("result ? ", result);
});
};
위와같이 콘솔에 찍어보았을땐 각각의 url에서 응답받은 데이터가 콘솔에 잘 찍힌다. 왜 map 메소드 실행 결과는 Promise { <pending> }
이 될까? 구글링을 해보았다.
await aync map
라고 검색해보니 지금 내가 고민하고있는 문제를 다루는 글이 있었다..!!
await
는 Promise 객체를 실행하고 기다려주지만, Promise 배열로는 그렇게 할 수 없기 때문이라는 사실을 알게되었다. 지금 위의 코드는 arr.map
을 통해 Promise 배열을 리턴하게 구현했기때문에 await
가 의미가 없다.
상황에 따라 위의 2가지 방법중 하나를 선택한다.
Promise.all
Promise.race
const fetchUsersAndWriteToFileAsync = async (readFilePath, writeFilePath) => {
const dataList = await getDataFromFilePromise(readFilePath); // [1,2,3,4,5]
const responseDataList = await Promise.all(
dataList.map(id => {
return getBodyFromGetRequestPromise(BASE_URL + id);
})
);
console.log("responseDataList ? ", responseDataList);
};
위와같이 코드를 수정하니 원하던 결과값을 얻을 수 있었다.
추가)))
for ...of를 사용해 해결하는 방법도 있다
async function processArray(array) {
for (const item of array) {
await delayedLog(item);
}
console.log('Done!');
}
// output
1
2
3
Done!
map, reduce 함수에서 async/await 쓰기
async/await를 이용한 비동기 loop 병렬로 순차 처리하기
Promise
자바스크립트 Promise 쉽게 이해하기
도움이 많이 됐습니다! 고민하던 부분이 한 번에 풀렸네요😆