반응형

 

 

async/await 키워드는 프로미스를 비동기가 아닌 동기적으로 작동시킵니다.

 

async/await는 간단한 키워드로 비동기 작업을 수행하는 promise를 동기적으로 동작하게끔 만들 수 있습니다.

함수 앞에 async 키워드를 붙이면 그 함수 내에서 await 키워드를 사용할 수 있습니다.

await 키워드가 붙은 프로미스는 비동기가 아닌 동기적으로 작업을 수행합니다.

 

아래에 await 키워드가 붙은 프로미스와 붙지 않은 프로미스의 비교 예시에서 콘솔 출력을 보면 await이 붙은 프로미스 뒤에 있는 코드들은 프로미스 작업이 끝날 때까지 기다렸다가 실행된다는 것을 알 수 있습니다.

 

* await이 붙은 프로미스와 붙지 않은 프로미스의 비교

// 프로미스 함수
const promise = () => new Promise((resolve, reject) => {
  setTimeout(() => {
    const success = Math.random() > -1;
    
    console.log("result: ", success);
    
    if (success) {
      resolve("success");
    } else {
      reject("failure");
    }
  }, 1000);
});

const myAsync = () => {
  const result = promise();
  console.log("end");
};

// async/await 을 사용
const myAsync1 = async () => {
  const result = await promise();
  console.log("end");
};

myAsync();
myAsync1();

 

myAsync를 실행하면 콘솔에 end가 먼저 출력되고 1초 뒤에 result: true가 출력됩니다. 프로미스는 비동기적으로 실행되기 때문에 promise() 실행 시작 후 바로 console.log("end")가 바로 실행되었기 때문입니다.

반면, myAsync1을 실행하면 콘솔에 1초 뒤에 result: true 가 먼저 출력되고 end가 나중에 출력됩니다. await키워드와 함께 쓰인 프로미스는 동기적으로 처리되기 때문에 promise() 실행완료를 기다렸다가 다음 줄인 console.log("end")가 실행되기 때문입니다.

 

 

 

async 키워드를 붙이면 그 함수는 Promise를 리턴하는 함수가 됩니다.

 

async 키워드가 붙은 함수는 promise를 리턴합니다. 따라서 함수 실행 이후 프로미스 체이닝이 가능합니다.

체이닝을 통해 함수의 리턴값은 then 메소드의 첫번째 파라미터로 전달할 수 있습니다.

위 예제에서 만든 myAsync1 함수에 리턴값을 추가하겠습니다.

const myAsync1 = async () => {
  const result = await promise();
  console.log("end");
  
  return "success!!";
};

 

myAsync1().then(res => console.log("res: ", res));

 

위 코드의 실행결과 콘솔에 찍히는 순서는 다음과 같습니다.

result: true
end
res: success!!

 

흐름은 다음과 같습니다.

myAsync1 첫째 줄에서 promise 함수가 실행됩니다. await 키워드가 있기 때문에 동기적으로 실행되고 promise 함수 내부 코드에 의해 result: true가 먼저 출력됩니다. 프로미스 실행이 끝나길 기다렸다가 끝난 이후에 myAsync1함수 내부 코드에 의해 end가 출력됩니다. 그리고 myAsync1은 "success!!" 결과값을 가진 프로미스 객체를 반환하고 이후 then 메소드가 실행됩니다. 결과값은 then 메소드로 전달되므로 res: success!!가 출력됩니다.

 

 

 

 

 

 

예외처리

 

위 promise 함수를 실패하는 경우도 발생하도록 변경하겠습니다.

 

// 프로미스 함수
const promise = () => new Promise((resolve, reject) => {
  setTimeout(() => {
    const success = Math.random() > 0.5;
    
    if (success) {
      resolve("success");
    } else {
      reject("failure");
    }
  }, 1000);
});

 

Math.random() > 0.5를 만족하지 못하면 reject("failure")를 실행하고 이것은 비동기작업 수행 실패를 의미합니다.

위에서 만든 myAsync1은 예제를 위한 예제로 정해진 문자열을 반환하는 것이 실용적이지 않습니다. promise 함수가 반환하는 값을 바로 반환하는 myAsync2를 만들겠습니다.

 

const myAsync2 = async () => {
  return await promise();
};

 

이전에 사용했던 다음 코드에는 프로미스 수행 실패에 대한 처리가 되어있지 않습니다.

 

myAsync1().then(res => console.log("res: ", res));

 

catch를 추가하면 예외처리를 할 수 있습니다. 이 경우 catch 메소드는 reject()로 전달하는 값을 첫번째 파라미터로 받을 수 있습니다. myAsync2를 이용해 새로운 프로미스 체이닝 코드를 작성하겠습니다.

 

myAsync2().then(res => console.log("result: ", res)).catch(err => console.log("error: ", err));

 

프로미스 실행이 성공하면 result: success가 출력되고 실패하면 error: failure가 출력됩니다. 확률은 반반이기 때문에 반복해서 호출하면서 두 가지 경우를 모두 확인할 수 있습니다.

 

 

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기