자바스크립트의 비동기 호출이란 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성을 의미
DOM Element의 이벤트 핸들러
마우스, 키보드 입력 (click, keydown 등)
페이지 로딩 (DOMContentLoaded 등)
타이머
타이머 API (setTimeout 등)
애니메이션 API (requestAnimationFrame)
서버에 자원 요청 및 응답
fetch API
AJAX (XHR)
일정 시간 후에 함수를 실행
setTimeout(function() {
console.log('1초 후 실행');
}, 1000);
// 123
일정 시간의 간격을 가지고 함수를 반복적으로 실행
setInterval(function() {
console.log('1초마다 실행');
}, 1000);
// 345
setTimeout 타이머를 종료
const timer = setTimeout(function() {
console.log('3초 후 실행');
}, 3000);
clearTimeout(timer);
// setTimeout 타이머를 취소함
반복 실행 중인 타이머를 종료
const intervalTimer = setInterval(function() {
console.log('1초마다 실행');
}, 1000);
clearInterval(timer);
// 더 이상 반복 실행되지 않음
비동기를 제어하는 기본적인 방법은 callback
함수를 사용하여 제어한다.
비동기로 처리할게 많아지면 callback chain(Hell)
에 빠진다.
callback chain의 단점
- 가독성이 안좋음
- 비즈니스 로직을 이해하기 힘듦
- 디버깅 할 때 굉장히 복잡해지고 어려움
- 유지/보수가 안좋음
Promise
는 JS에서 제공하는 비동기 코드를 간편하게 처리할 수 있도록 도와주는 object
이다.
Promise
는 어떤 기능을 실행하고 나서 정상적으로 동작하면 성공의 메세지와 함께 처리된 결과값을 전달해줌
그러나 기능을 수행하다 예상치 못한 문제가 발생하면 error를 전달해 준다.
Promise State: pending (보류) → fulfilled (이행) or rejected (거부)
const promise = new Promise((resolve, reject) => {
// 시간이 오래 걸리는 무거운 처리 (network, read files ..)
console.log(`doing something...`);
setTimeout(() => {
resolve(`success`); // 성공 하면
// reject(new Error(`no network`)); // 실패 하면
}, 2000);
});
resolve
: 처리 성공할 시 인자를 넘겨줌reject
: 에러(실패)가 날시 인자를 넘겨줌promise
.then((value) => { // resolve 인자를 받음
console.log(value);
})
.catch(error => { // reject 인자를 받음
console.log(error);
})
.finally(() => { // 성공하든 실패하든 마지막에 실행됨
console.log(`finally`);
})
then으로 값을 바로 전달 할 수 도 있고, 리턴으로 Promise를 전달할 수 있다.
Promise.all
([함수, 함수]) : Promise 비동기 처리를 배열 형태로 간단하게 묶어줌
Promise.race
([함수, 함수]) : 비동기 처리중 먼저 리턴하는 것만 출력
Promise chaining도 계속 중첩되면 callback chain처럼 코드의 가독성이 떨어짐
async
와 await
은 Promise
를 간결/간편하고 동기적으로 실행되는것 처럼 보이게 만들어주는 API
await
은 async
함수 내부에서만 사용 가능
try
, catch
로 에러를 처리함
function delay(ms) {
return new Promise (resolve => setTimeout(resolve, ms));
}
async function getApple() {
await delay(1000);
// throw new Error(`error: apple`); // error 발생
return `🍎`;
}
async function getBanana() {
await delay(1000);
// throw new Error(`error: banana`);
return `🍌`;
}
async function pickFruits() {
let apple = null;
try {
apple = await getApple();
} catch(error) {
console.log(error);
}
let banana = null;
try {
banana = await getBanana();
} catch(error) {
console.log(error);
}
return `${apple} + ${banana}`;
}
pickFruits().then(result => console.log(result));
const fs = require('fs')
npm install [모듈명] // CLI
const 모듈변수 = require('모듈명'); // 모듈 설치후 불러옴
fs.readFile(path[, options], callback) 기본 형태
fs.readFile('test.txt', 'utf8', (err, data) => {
if (err) {
throw err; // 에러를 던짐
}
console.log(data);
});
비동기 요청인 네트워크 요청 중 URL
로 요청하는 경우 사용하는 API
웹사이트에서는 해당 정보만 업데이트하기 위해 자바스크립트 그 중에서도 fetch API
를 사용해 해당 정보를 원격 URL로부터 불러옴
fetch API
는 특정 URL로부터 정보를 받아오는 역할을 해주며 이 과정이 비동기로 이루어지기 때문에 경우에 따라 다소 시간이 걸리는 작업을 요구할 경우 blocking
이 발생하면 안되므로 특정 DOM
에 정보가 표시될때까지 로딩창을 대신 띄우는 경우도 많이 있다.
const url = 'URL 주소';
fetch(url)
.then(response => response.json()) // 요청 받은 것을 json으로 변환시켜 응답함
.then(json => console.log(json))
.catch(error => console.log(error));
fetch API
는 Promise
의 형식으로 이루어짐
(chaining
, Promise.all
, async
/await
사용 가능)