써먹는 웹개발
[ES6] 비동기 처리의 시작 (callback, promise, async, await) 본문
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초 후에 출력 |
728x90
반응형
'웹개발 > ES6, ES2020' 카테고리의 다른 글
[ES2020] 옵셔널 체이닝 (0) | 2021.12.03 |
---|---|
[ES6] 비구조화 할당 (0) | 2021.04.16 |
[ES6] For.. of와 For.. in의 차이 (0) | 2020.11.12 |
[ES6] 모듈기반 서비스코드 구현방법 (export & import) (0) | 2020.08.06 |
[ES6] 객체의 Prototype 변경 (0) | 2020.08.06 |
Comments