비동기 1편에서 핸들러를 중첩적으로 사용하여 프로미스 지옥이 발생했다.
async/await
으로 프로미스 지옥을 해결해보자.
async
와 await
은 기존의 Promise
를 보다 간결하게 작성할 수 있도록 도와주는 문법이다. 눈에 보이는 문법만 다를 뿐, 내부적으로는 프로미스 방식으로 비동기 작업을 처리한다.
async
는 함수 앞에, await
은 비동기로 처리되는 부분 앞에 붙인다. async
는 await
을 사용하기 선언문으로 함수 내에서 await
을 사용할 수 있도록 만든다.
await
을 사용하기 위해서는async
가 필요하다.async
가 없는 함수에서await
을 사용하면 에러가 발생한다.
await
은 비동기 처리가 완료될 때까지 코드 실행을 일시 중지하고 기다린다. 즉, 비동기 작업을 동기적으로 처리할 수 있도록 도와준다.
const delay = (sec) => {
return new Promise((resolve) => {
resolve(sec);
}, sec);
};
const asyncFunc = async () => {
await delay(1000);
console.log('1 sec passed');
};
asyncFunc();
💥 프로미스 지옥 해결하기
const write = (path, data) => {
return new Promise((resolve, reject) => {
fs.writeFile(path, data, (err) => {
if(err) {
reject();
}
resolve();
});
});
};
const read = (path) => {
return new Promise((resolve, reject) => {
fs.readFile(path, (err, data) => {
if(err) {
reject();
}
resolve(data.toString());
});
});
}
write(path, data).then(() => {
read(path).then((data) => {
write(path, data).then(() => {
read(path).then(...);
});
});
});
위의 코드는 then
핸들러를 중첩적으로 사용하여 가독성이 떨어진다. 프로미스 지옥을 async
와 await
을 사용하여 해결해보자.
const asyncFunc = async () => {
await write(path, data);
const d1 = await read(path);
await write(path, d1);
const d2 = await read(path);
...
}
asyncFunc();
파일 입출력을 동기적으로 처리하기 위해 await
을 사용했고, await
을 사용하기 위한 async
키워드를 함수 앞에 붙여준다. 파일을 작성한 후에 파일 내용을 읽어오고, 읽어온 내용을 다시 파일에 쓴다. 코드가 간결해지고 가독성이 높아진 것을 확인할 수 있다.
참고자료
자바스크립트 async/await