본문 바로가기

Language/Javascript

[Javascript] async, await

728x90
반응형

async, await를 사용하면 Promise의 then 함수를 체이닝 형식으로 호출하는 것보다 가독성이 좋아진다. 

 

 

async

함수 앞에 async를 붙이면 항상 Promise를 반환한다.

async function getName() {
    return "Mike";
}

console.log(getName());  // Promise {<fullfilled>: "Mike"}

getName().then((name) => {
    console.log(name);   // "Mike"
});

 

리턴값이 프로미스이면 리턴한 프로미스를 그대로 사용한다.

async function getName() {
    return Promise.resolve('Tom');
}

getName().then((name) => {
    console.log(name);   // "Mike"
});

 

함수 내부에서 예외가 발생하면 rejected 상태의 프로미스가 반환된다.

async function getName() {
    throw new Error("err..");
}

getName().catch((err) => {
    console.log(err);   // Error: err..
});

 

 

await 

await 키워드는 async 내부에서만 사용할 수 있다.

function getName(name) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(name);
        }, 1000);
    });
}

async function showName() {
    const result = await getName('Mike');
    console.log(result);
}

console.log("시작");
showName();

시작하고 1초 뒤에 Mike가 찍힌다. getName에서 리저브된 값을 기다렸다가 result에 넣어주는 것이다.

 


const f1 = () => {
    return new Promise((res, rej) => {
        setTimeout(() => {
            res("1번 주문 완료");
        }, 1000);
    });
};

const f2 = (message) => {
    console.log(message);
    return new Promise((res, rej) => {
        setTimeout(() => {
            res("2번 주문 완료");
        }, 3000);
    });
};

const f3 = (message) => {
    console.log(message);
    return new Promise((res, rej) => {
        setTimeout(() => {
            res("3번 주문 완료");
        }, 2000);
    });
};

console.log("시작");
f1()
    .then((res) => f2(res))
    .then((res) => f3(res))
    .then((res) => console.log(res))
    .catch(console.log)
    .finally(() => {
        console.log("끝");
    });

이 코드를 async, await를 이용해서 바꾸면

const f1 = () => {
    return new Promise((res, rej) => {
        setTimeout(() => {
            res("1번 주문 완료");
        }, 1000);
    });
};

const f2 = (message) => {
    console.log(message);
    return new Promise((res, rej) => {
        setTimeout(() => {
            res("2번 주문 완료");
        }, 3000);
    });
};

const f3 = (message) => {
    console.log(message);
    return new Promise((res, rej) => {
        setTimeout(() => {
            res("3번 주문 완료");
        }, 2000);
    });
};

console.log("시작");
async function order() {
    const result1 = await f1();
    const result2 = await f2(result1);
    const result3 = await f3(result2);
    console.log(result3);
    console.log('종료');
}
order();

이렇게 된다. then을 쓰는 것보다 가독성이 좋아진다.

 

rejected인 경우에는 어떻게 될까?

const f1 = () => {
    return new Promise((res, rej) => {
        setTimeout(() => {
            res("1번 주문 완료");
        }, 1000);
    });
};

const f2 = (message) => {
    console.log(message);
    return new Promise((res, rej) => {
        setTimeout(() => {
            // res("2번 주문 완료");
            rej(new Error("err.."));
        }, 3000);
    });
};

const f3 = (message) => {
    console.log(message);
    return new Promise((res, rej) => {
        setTimeout(() => {
            res("3번 주문 완료");
        }, 2000);
    });
};

console.log("시작");
async function order() {
    try {
        const result1 = await f1();
        const result2 = await f2(result1);
        const result3 = await f3(result2);
        console.log(result3);
    } catch(e) {
        console.log(e);
    }
    console.log('종료');
}
order();

2번을 rejected로 바꿨다. Promise에서는 catch 함수를 썼는데 async, await 함수에서는 try-catch문으로 감싸주면 된다.

728x90
반응형