개발 이야기/개발 도서

제로초 자바스크립트 입문 <프로미스와 async / await>

sonoa 2024. 3. 12. 14:35
반응형

프로미스 

  • promise 라는 클래스를 사용하는 문법
  • new 를 붙여 Promise 클래스를 호출하면 프로미스 객체를 생성하는데, 이때 인수로 콜백 함수를 넣는다
const <프로미스 객체> = new Promise((resolve, reject) => {
  resolve(); // 프로미스 성공 
  // 또는 
  reject(); // 프로미스 실패
});

<프로미스 객체>.then(<콜백 함수>);
// 또는 
<프로미스 객체>.catch(<콜백 함수>);
  • then( ) 의 콜백 함수는 resolve( ) 함수를 호출할 때 실행
  • catch( ) 의 콜백 함수는 reject( ) 함수를 호출할 때 실행 
  • resolve( ) 의 인수로 전달한 값은 then( ) 콜백 함수의 매개변수로 전달 
  • reject( ) 의 인수로 전달한 값은 catch( ) 콜백 함수의 매개변수로 전달 
const p1 = new Promise((resolve, reject) => {
  resolve('success');
});
p1.then((data) => console.log(data)); // success
const p2 = new Promise((resolve, reject) => {
  reject('error');
});
p2.catch((error) => console.log(error)); // error
  • reject( ) 호출했는데 catch( ) 메서를 붙이지 않으면 에러 발생
  • 아래 코드는 비동기 코드를 프로미스 문법으로 전환한 것 
// 비동기 코드 
const timerId = setTimeout(() => {
  console.log('0초 뒤에 실행됩니다.');
}, 0);

// 프로미스 문법 
const setTimeoutPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve();
  }, 0);
});
setTimeoutPromise.then(() => {
      console.log('0초 뒤에 실행됩니다.');
    });
  • 프로미스를 실행된 결과 값을 저장하고 있으며, 언제든지 필요할 때 그 값을 꺼낼 수 있는 객체라 할 수 있다 
const p1 = new Promise((resolve, reject) => {
  resolve('프로미스 작업을 합니다.');
});
console.log('다른 일을');
console.log('열심히');
console.log('하다가');
p1.then(console.log); 
다른 일을
열심히
하다가
프로미스 작업을 합니다.

---------------------------------------------------------------------
const setTimeoutPromise = (ms) => new Promise((resolve, reject) => {
  setTimeout(resolve, ms);
  });
const promise = setTimeoutPromise(0);
console.log('다른 일을 하다가');
console.log('필요할 때');
console.log('then을 호출해 보세요.');
promise.then(() => {
  console.log('0초 뒤에 실행됩니다.');
});
promise.catch((err) => {
  console.log('에러 발생 시 실행됩니다.');
});
다른 일을 하다가
필요할 때
then을 호출해 보세요.
0초 뒤에 실행됩니다.

---------------------------------------------------------------------
const promise = setTimeoutPromise(0);
promise
  .then(() => {
        return 'a';
  })
  .then((data) => {
    console.log(data); // a
    return 'b';
  })
  .then((data) => {
    console.log(data); // b
      });
  • then( ) 과 catch( ) 의 실행이 끝난 후에 finally( )가 있으면 무조건 실행
const promise = setTimeoutPromise(0);
promise
  .then(() => {
        console.log('0초 뒤에 실행됩니다.');
  })
  .catch((err) => {
    console.log('에러 발생 시 실행됩니다.');
  })
  .finally((err) => {
    console.log('성공이든 실패든 무조건 실행됩니다.');
      });

async / await 

const setTimeoutPromise = (ms) => new Promise((resolve, reject) => {
  setTimeout(resolve, ms);
});
setTimeoutPromise(1000).then(() => {
  console.log('1초 뒤에 실행됩니다.');
});
console.log('내가 먼저');
내가 먼저
1초 뒤에 실행됩니다.
  • 이것을 개선하려면 async / await  문법을 사용
const setTimeoutPromise = (ms) => new Promise((resolve, reject) => {
  setTimeout(resolve, ms);
});
    await setTimeoutPromise(1000);
    console.log('1초 뒤에 실행됩니다.');
    console.log('내가 나중에');
    1초 뒤에 실행됩니다.
내가 나중에
  • await 는 프로미스가 resolve() 할 때가지  기다리라는 뜻이다
  • await 를 사용하면 프로미스인 비동기 코드를 순서대로 실행하게 만든다 
const setTimeoutPromise = (ms) => new Promise((resolve, reject) => {
  setTimeout(resolve, ms);
});
    async function main() {
      await setTimeoutPromise(1000);
  console.log('1초 뒤에 실행됩니다.');
  console.log('내가 나중에');
}
main();
1초 뒤에 실행됩니다.
내가 나중에

---
// 화살표 함수 
const setTimeoutPromise = (ms) => new Promise((resolve, reject) => {
  setTimeout(resolve, ms);
});
    const main = async () => {
      await setTimeoutPromise(1000);
  console.log('1초 뒤에 실행됩니다.');
}
main();
1초 뒤에 실행됩니다.

 

try-catch 문으로 에러 처리하기

  • try-catch 으로 reject( )의 인수로 넣었던 값이 catch 문의 error 로 전달 
const p1 = new Promise((resolve, reject) => {
  reject('에러!');
});
    try {
      await p1;
    } catch (error) {
  console.log(error); 
}
    에러!
  • catch 문의 error 는 사용하지 않는 경우 생략 
  • Promise 의 finally 처럼 try-catch 문에도 finally 문을 추가할 수 있다
const p1 = new Promise((resolve, reject) => {
  reject('에러!');
});
try {
  await p1;
    } catch {
  console.log('에러인 경우');
} finally {
  console.log('성공이든 에러든 마지막에 실행됩니다.');
}
    에러인 경우
성공이든 에러든 마지막에 실행됩니다.
반응형