async/await
async/await 문법은 프로미스를 사용한 코드를 한번 다 깔끔하게 줄입니다.
function findAndSaveUser(users) {
Users.findOne({})
.then((user) => {
user.name = 'zero';
return user.save();
})
.then((user) => {
return Users.findOne({ gender: 'm' });
})
.then((user) => {
// 생략
})
.catch(err => {
console.error(err);
});
}
콜백과 다르게 코드의 길이가 길어지지 않지만, 코드는 여전히 깁니다. async/await 문법을 사용하면 다음과 같이 바꿀 수 있습니다.
async function이라는 것이 추가되었습니다.
async function findAndSaveUser(users) {
let user = await Users.findOne({});
user.name = 'zero';
user = await user.save();
user = await Users.findOne({ gender: 'm' });
// 생략
}
함수 선언부를 일반 함수 대신 async function으로 교체한 후, 프로미스 앞에 await을 붙였습니다. 이제 함수는 해당 프로미스가 resolve될 때까지 기다린 뒤 다음 로직으로 넘어갑니다.
위 코드는 에러를 처리하는 부분(프로미스가 reject가 된 경우)이 없으므로 다음과 같은 추가 작업이 필요합니다.
async function findAndSaveUser(Users) {
try {
let user = await Users.findOne({});
user.name = 'zero';
user = await user.save();
user = await Users.findOne({ gender: 'm' });
// 생략
} catch (eror) {
console.error(error);
}
}
try/catch문으로 로직을 감싸겠습니다. 프로미스의 catch 메소드처럼 try/catch문의 catch가 에러를 처리합니다.
화살표 함수로 async와 같이 사용할 수 있습니다.
const functionAndSaveUser = async (Users) => {
try {
let user = await Users.findOne({});
user.name = 'zero';
user = await user.save();
user = await User.findOne({ gender: 'w' });
// 생략
} catch (error) {
console.error(error);
}
}
for 문과 async/await를 같이 써서 프로미스를 순차적으로 실행할 수 있습니다.
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
(async () => {
for (await (promise of [promise1, promise2]) {
console.log(promise);
}
})();
for await of 문을 사용해서 프로미스 배열을 순회하는 모습입니다. async 함수와 반환 값은 항상 Promise로 감싸집니다. 따라서 실행 후 then을 붙이거나 또 다른 async 함수 안에서 await을 붙여서 처리할 수 있습니다.
async function findAndSaveUser(Users) {
// 생략
}
findAndSaveUser().then(() => { /* 생략 */} );
// 또는
async function order() {
const result = await findAndSaveUser();
}