써먹는 웹개발

[ES6] 비동기 처리의 시작 (callback, promise, async, await) 본문

웹개발/ES6, ES2020

[ES6] 비동기 처리의 시작 (callback, promise, async, await)

kmhan 2021. 4. 16. 01:57


728x90
반응형

비동기 처리의 시작

 

0. 사전 정보

 - 자바스크립트는 동기적인 특성이 있어 첫번째 행의 소스가 실행된 다음에 두번째 행의 소스가 실행된다.

 - hoisting : var, function 선언들이 (작성 순서와 상관없이) 제일 먼저 실행되는 것

 - 동기 처리 : 첫번째 요청이 끝날때까지 다른 요청이 들어올 수 없는 처리방식

   비동기 처리 : 첫번째 요청이 들어와도 다른 요청 작업을 진행할 수 있는 처리방식

     [동기와 비동기. 출처= 한빛미디어 Boost.Asio를 이용한 네트워크 프로그래밍]

 

1. callback

1-1. 정의

     1) 다른 함수의 인자로써 이용되는 함수

     2) 어떤 이벤트에 의해 호출되어지는 함수.

1-2. 예제

console.log('1');
setTimeout(() => console.log('2'), 1000);
console.log('3');

// Synchronous(동기) callback
function printImmediately(print) {
  print();
}
printImmediately(() => console.log('hello'));

// Asynchronous(비동기) callback
function printWithDelay(print, timeout) {
  setTimeout(print, timeout);
}
printWithDelay(() => console.log('async callback'), 2000);
결과

 

2. promise

2-1. 정의 : 비동기를 간편하게 처리할 수 있는 객체

2-2. 예제 

1) Producer vs Consumer

// 1. Producer
const promise = new Promise((resolve, reject) => {
  // 네트워크나 파일읽기에 유용
  console.log('doing something...');
  setTimeout(() => {
    resolve('ellie'); // resolve는 then을 호출
    // reject(new Error('no network')); // reject는 catch를 호출
  }, 2000);
});

// 2. Consumers: then, catch, finally
promise
.then(value => {
  console.log(value);
})
.catch(error => {
  console.log(error);
})
.finally(() => {
  console.log('finally');
});

// 3. Promise chaining
const fetchN
resolve 호출

reject 호출

2) Promise 연결하기

// Promise chaining
const fetchNumber = new Promise((resolve, reject) => {
  setTimeout(() => resolve(1), 1000);
});

fetchNumber
.then(num => num * 2)
.then(num => num * 3)
.then(num => {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(num - 1), 1000);
  });
})
.then(num => console.log(num));
'5' 출력

3) 에러 핸들링

// Error Handling
const getHen = () =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve('닭'), 1000);
  });
const getEgg = hen =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve('${hen} => '알'), 1000);
  });
const cook = egg =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve('${egg} => 요리'), 1000);
  });

// getEgg에서 발생한 문제를 예외처리하고 싶다면
getHen()
   .then(getEgg)
   .then(cook)
   .then(console.log)
   .catch(console.log);
닭 => 알 => 요리

3-2) 에러 핸들링에서 중간에 예외처리 방법

// Error Handling
const getHen = () =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve('닭'), 1000);
  });
const getEgg = hen =>
  new Promise((resolve, reject) => {
    setTimeout(() => reject(new Error('error! ${hen} => 알')), 1000);
  });
const cook = egg =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve('${egg} => 요리'), 1000);
  });

// getEgg에서 발생한 문제를 예외처리하고 싶다면
getHen()
   .then(getEgg)
   .catch(error => {
     return '빵';
   })
   .then(cook)
   .then(console.log)
   .catch(console.log);
빵 => 요리

 

3. async/await

3-1. 정의 

 1) async : promise를 더 간략히 사용가능

 2) await : 해당 문법이 끝날때까지 동기처리

3-2. 예제

 1) async

async function fetchUser() {
  return 'ellie';
}

console user = fetchUser();
user.then(console.log);
console.log(user);

 2) await

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function getApple() {
  await delay(1000); // await은 1초간 기다려준다. (await이 없으면 기다림 기능과 별개로 바로 return 된다.)
  return '사과';
}

async function getBanana() {
  await delay(1000);
  return '바나나';
}

// async 및 await 방식
async function pickFruits() {
  const apple = await getApple();
  const banana = await getBanana();
  return '${apple} + ${banana}';
}

/* promise 방식 (위와 동일한 기능의 소스)
function pickFruits() {
  return getApple()
  .then(apple => {
     return getBanana().then(banana => '${apple} + ${banana}');
  })
}
*/

pickFruits().then(console.log);
사과 + 바나나 // 실행하고 2초 후에 출력

 2-2) await 병렬처리

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function getApple() {
  await delay(1000); // await은 1초간 기다려준다. (await이 없으면 기다림 기능과 별개로 바로 return 된다.)
  return '사과';
}

async function getBanana() {
  await delay(1000);
  return '바나나';
}

// async 및 await 방식
async function pickFruits() {
  const applePromise = getApple();
  const bananaPromise = getBanana();
  const apple = await applePromise;
  const banana = await bananaPromise;
  return '${apple} + ${banana}';
}

pickFruits().then(console.log);
사과 + 바나나 // 실행하고 1초 후에 출력

 2-3) Promise를 이용한 병렬처리

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function getApple() {
  await delay(1000); // await은 1초간 기다려준다. (await이 없으면 기다림 기능과 별개로 바로 return 된다.)
  return '사과';
}

async function getBanana() {
  await delay(1000);
  return '바나나';
}

// 개선된 Promise 방식
function pickAllFruits() {
  return Promise.all([getApple(), getBanana()])
  .then(fruits => fruits.join(' + '));
}
pickAllFruits().then(console.log);

/* Tip. 둘 중에 먼저 호출되는 것 하나만 가져오고 싶다면 race를 쓸 것
function pickOnlyOne() {
  return Promise.race([getApple(), getBanana()]);
}
*/
사과 + 바나나 // 실행하고 1초 후에 출력

 

강의 출처 : www.youtube.com/watch?v=s1vpVCrT8f4

728x90
반응형


Comments