동기(Synchronous)
- 블로킹(blocking)
: 한 작업이 실행되는 동안 다른 작업은 멈춘 상태를 유지하고 자신의 차례를 기다리는 방식비동기(Asynchronous)
- 논블로킹(Non-blocking)
: 어떠한 요청을 보내면 그 요청이 끝날 때까지 기다리는 것이 아니라, 응답에 관계없이 바로 다음 동작이 실행되는 방식
비동기 처리의 필요성
- 효율성을 상승시켜 처리 속도 향상
- 서버와 통신을 할 때 많은 시간이 소요되므로 네트워크 관련 작업에 필요
- 자바스크립트 외적인 것, 가령 DOM에 접근하는 메소드 혹은 브라우저가 제공하는 API 등에 필요
싱글스레드를 지닌 자바스크립트가 비동기 처리가 가능한 이유?
⇒ 이벤트 루프(Event Loop) + 큐(Queue)*큐 - 비동기 작업을 마친 후 실행될 콜백함수가 쌓이는 곳 ex)Task Queue(=Job Q)
Javascript에서 비동기 구현 방식
1. Callback function
2. Promise
3. Async/Await
*callback?
: 함수를 활용하는 방법 중 하나로, 파라미터로 전달받은 함수를 일컫는다.
=> 함수 안에서 실행하는 또 다른 함수
*promise?
: 콜백 함수의 단점을 보완하며(call back hell) 비동기 처리에 사용되는 객체
=> 성공 시 resolve, 실패 시 reject를 return
*async/awiat?
: promise의 사용성을 높인 문법
=> async 함수는 항상 promise를 반환, await 키워드를 만나면 promise가 처리될 때까지 대기
Callback
setTimeout(() => { console.log("이 함수는 약 1분 후 실행!"); }, 60000); setInterval(() => { console.log("이 함수는 약 10초마다 실행!"); }, 10000);
Callback hell
setTimeout(() => { asyncFn(() => { const a = 1; asyncFn2(() => { const b = 2; asyncFn3(() => { asyncFn4(() => { ... }); }); }); }); }, 1000);
Promise
function p() { return new Promise((resolve, reject) => { resolve('hello'); // or reject(new Error('error'); }); ) p.then((n) => console.log(n);
Promise 패턴의 문제
- 연결되는 비동기 함수가 많아질수록 길어지는 then 체인
function promisifiedSetTimeout(seconds){ return new Promise((resolve, reject) => { setTimeout(() => { resolve(); }, seconds); }); } // then-then-then-then.. promisifiedSetTimeout(1000) .then(asyncFn1) .then(asyncFn2) .then(asyncFb3) .then(() => { // do something })
async/await
async function asyncFunc() { let data = await fetchData() let user = await fetchUser(data) return user }
- promise를 활용한 비동기 코드를 간결하게 작성하는 문법
- 비동기 코드를 '동기 코드처럼' 간결하게 작성 가능
- async로 선언된 함수는 반드시 Promise를 리턴
await 키워드 실행 순서
- await 키워드는 then 메서드 체인을 연결한 것과 같이 순서대로 동작
- 비동기 코드에 쉽게 순서 부여
async function p2() { return 'hello'; } console.log(p2()); p2().then(n) => console.log(n);
async-await 병렬 처리
function delay(ms) { return new Promise(resolve, setTimeout(() => resolve, ms) } async function getApple() { await delay(3000); return 'Apple'; } async function getBanana() { await dealy(3000); return 'Banana'; }
- Promise의 특징을 활용한 방법
function pickFruits() { const applePromise = getApple(); const bananaPromise = getBanan(); // promise 선언 즉시, 실행 되는 특성을 이용한 병렬처리 const apple = await applePromise; const banana await bananaPromise; return `${apple} + ${banana}`; }
- Promise.all() 메소드를 활용한 방법
function pickAllFruits() { return Promise.all([getApple(), getBanana()]).then(fruits => fruits.join(' + ') ); } pickAllFruits().then(console.log);
- Promise.race() 메소드
function pickOnlyOne() { return Promise.race([getApple(), getBanana()]); } pickOnlyOne().then(console.log);
출처 - [엘리스 SW 엔지니어 트랙 4기 강의 자료], 드림 코딩