자바스크립트는 동기적이다. 그런데
파일에서 큰 데이터를 가져오는 행위를 동기적으로 처리하게 된다면, 파일을 읽어오고 네트워크에서 데이터를 받아오는 동안 다음 라인 코드가 실행 되지 않기 때문에 시간이 걸리는 것들은 비동기적으로 처리하는 것이 좋다.
예를 들어 동기적으로 사이트를 만든다면 웹사이트에서 접속해서 이미지가 로딩될 동안 사용자는 빈 화면만 보게 되는 불상사가 생길 수도있다. 자바스크립트에서도 비동기 방식으로 작업 할 수 있다.
1. Callback
callback함수를 이용하여 비동기 프로그래밍을 구현할 수 있다. 하지만 콜백 지옥에 갇혀 버릴 수 있다..
지난 TIL 참고2. Promise
ES6에서는 비동기 처리를 위한 또 다른 패턴으로 프로미스(Promise)를 도입했다.
Promise는 자바스크립트 안에 내장되어있는 객체다. 비동기를 수행할 때 콜백 함수 대신 유용하게 사용할 수 있다.3. async await
syntatic sugar인 asynce await 는 비동기처리의 최신문법이다. async await을 사용하면 promise를 깔끔하게 작성할 수 있다.
오늘은 Promise에 대해서 배웠다.
프로미스는 전통적인 콜백 패턴이 가진 단점을 보완하며 비동기 처리 시점을 명확하게 표현할 수 있다는 장점이 있다.
const Promise = new Promise((resolve, reject) => {
//doing some heavy work (network, read files)
})
Promise는 클래스이기때문에 new라는 클래스로 오브젝트 생성 가능하다.
새로운 Promise를 만들면 executor라는 콜백 함수가 자동적으로 실행이 된다. 콜백 함수는 또 두가지로 나뉘는데 resolve, reject가 있다.
유의 사항: Promise를 만든순간 콜백함수가 자동적으로 실행된다는 것을 유의해야한다.
Promise는 기능을 수행하다가 성공할 수도 있고, 실패할 수도 있다.
성공 -> resolve 를 호출
실패 -> reject 를 호출
setTimeout
을 이용하여 시간 차를 두고, 데이터를 받아온 것처럼 해봤다.
const promise(resolve, reject) => {
setTimeout(() => {
resolve('yejin') // 성공 했을 때 resolve 함수 호출하면서 값을 전달
}, 2000);
});
정상적으로 수행된다면 -> then으로 값을 받아오기
promise.then(value) => {
console.log(value); // yejin
});
// value라는 파라미터는 promise가 정상적으로 수행되어서 resolve 콜백함수에서 전달된 yejin이라는 값이 들어옴
실패했을 때 reject
const promise(resolve, reject) => {
setTimeout(() => {
reject(new Error('no network')); // reject는 보통 Error오브젝트로 값을 전달, 에러 사유도 정확히 입력해야함
}, 2000);
});
then의 에러처리 → .catch → 필요하면 .finally
// 성공케이스
promise
.then(value) => {
console.log(value); // yejin
})
//실패케이스
.catch(error => {
console.log(error);
});
.finally(() => {
console.log('finally!!');
});
then을 호출하게되면, then은 똑같은 promise를 return하기때문에 그 return된 promise에 catch를 다시 호출할 수 있는 것임 -> 메소드 체이닝
.finally라는 것은 성공 실패 여부와 상관없이 마지막에 무조건 호출되는 것을 말한다.
async와 await는 자바스크립트의 비동기 처리 패턴 중 가장 최근에 나온 문법 기존의 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완
function resolveAfter2Seconds() {
return new Promise(resolve => {
setTimeout(() => {
resolve('resolved');
}, 2000);
});
}
async function asyncCall() {
console.log('calling');
const result = await resolveAfter2Seconds();
console.log(result);
// expected output: "resolved"
}
asyncCall();
함수를 선언 할 때 함수의 앞부분에 async 키워드를 붙여준다. 그리고 Promise 의 앞부분에 await 을 넣어주면 해당 프로미스가 끝날때까지 기다렸다가 다음 작업을 수행 할 수 있다.
await는 async 함수 안에서만 동작하고 await는 말 그대로 Promise가 처리될 때까지 함수 실행을 기다리게 만든다.
Promise가 처리되길 기다리는 동안엔 엔진이 다른 일(다른 스크립트를 실행, 이벤트 처리 등)을 할 수 있기 때문에, CPU 리소스가 낭비되지 않는다.
회고
비동기처리 방식이 어렵다고들 하는데, promise패턴이 이해가 잘되고 재밌다. 나에겐 콜백패턴이 좀 더 어려운 느낌?.. 이번에 promise를 활용한 과제가 주어졌는데 실무로 적용하는건 어려울 것 같긴 하다. 개념 정리 확실히 하고 도전!!!!! 👊🏻