Hi, There!
안녕하세요, 바오밥입니다.
목차
- 개요
- 본문
- Reference
개요
자바스크립트의 프로미스 부분을 정리하였습니다.
본문
자바스크립트의 비동기 처리
자바스크립트는 비동기 처리란 특정 코드에 의해 실행된 연산이 종료되지 않았음에도 불구하고 다른 코드가 실행되는 특성을 말합니다.
자바스크립트의 비동기 처리 예시 - setTimeout
setTimeout은 이전 장에 잘 설명되어 있으니 참고 부탁드립니다.
스케쥴링 메서드 (setTimeout, setInterval)
코드의 흐름대로 실행되지 않고, 3초를 기다리는 동안 hello again이 미리 실행되어 버립니다.
console.log("hello!");
setTimeout(function(){
console.log("bye!");
}, 3000);
console.log("hello again!");
/*
hello -> hello again -> bye
*/
콜백 함수
비동기 처리의 문제점을 해결하기 위해 콜백 함수를 사용합니다.
콜백 함수는 모든 연산이 종료된 이후에 다음 코드가 실행될 수 있도록 도와줍니다.
이를 통해 웹 서비스 제공 시 데이터가 준비된 시점에만 코드가 실행될 수 있도록 합니다.
만약, 콜백 함수가 없다면 데이터를 받아오기 전에 화면을 그리기 때문에 빈 화면이 뜨게 되는 현상이 발생합니다.
그러나 콜백 함수는 함수 내에서만 값을 유지할 수 있다는 단점이 있습니다. 또한, 콜백 함수를 여러 번 사용하다보면 콜백 지옥에 빠질 수 있습니다.
콜백 함수 예제 (콜백지옥)
const order1 = (cb) => {
setTimeout(()=> {
console.log("1번 주문 완료");
cb();
}, 3000);
}
const order2 = (cb) => {
setTimeout(()=> {
console.log("2번 주문 완료");
cb();
}, 2000);
}
const order3 = (cb) => {
setTimeout(()=> {
console.log("3번 주문 완료");
cb();
}, 1000);
}
console.log("시작")
order1(()=>{
order2(()=>{
order3(()=>{
console.log("끝");
})
})
})
프로미스
프로미스는 콜백 함수의 단점을 보완한 함수입니다. 콜백 함수와 동일하게 비동기 처리의 문제점을 해결할 수 있습니다.
프로미스 예제
const pr = new Promise((res, rej) => {
setTimeout(()=> {
res("OK");
// rej(new Error("err..."));
}, 1000)
})
console.log("시작")
pr.then((result)=>{
console.log(result);
})
.catch((err) => {
console.log(err);
})
.finally(()=> {
console.log("끝");
})
// "시작"
// 1초 후 "OK"
// "끝"
콜백 지옥을 프로미스 체이닝으로!
const order1 = () => {
return new Promise((res,rej)=> {
setTimeout(()=>{
res("1번 주문 완료");
},1000)
})
}
const order2 = (message) => {
console.log(message)
return new Promise((res,rej)=> {
setTimeout(()=>{
res("2번 주문 완료");
},3000)
})
}
const order3 = (message) => {
console.log(message)
return new Promise((res,rej)=> {
setTimeout(()=>{
res("3번 주문 완료");
},2000)
})
}
console.log("시작")
order1()
.then((res)=>order2(res))
.then((res)=>order3(res))
.then((res)=>console.log(res))
.catch(console.log)
.finally(()=>{
console.log("끝")
})
만약 동시 주문을 하고 싶다면? Promise.all()
프로미스 체이닝을 사용하는 것보다 Promise.all()를 사용하는 것이 연산 속도가 더 빠릅니다.
다만, 프로미스 체이닝의 경우 reject 된 값까지 반환하는 반면, Promise.all()은 하나라도 reject 되면 값을 반환하지 않습니다.
하나의 정보라도 누락되면 페이지를 보여주면 안되는 경우 유용하게 사용될 수 있습니다.
const order1 = () => {
return new Promise((res,rej)=> {
setTimeout(()=>{
res("1번 주문 완료");
},1000)
})
}
const order2 = (message) => {
console.log(message)
return new Promise((res,rej)=> {
setTimeout(()=>{
res("2번 주문 완료");
},3000)
})
}
const order3 = (message) => {
console.log(message)
return new Promise((res,rej)=> {
setTimeout(()=>{
res("3번 주문 완료");
},2000)
})
}
console.log("시작")
Promise.all([order1(), order2(), order3()])
.then((res)=> {
console.log(res)
// ["1번 주문 완료","2번 주문 완료","3번 주문 완료"] 반환
})
제일 먼저 완료된 애만 수행! Promise.race()
Promise.race()는 제일 먼저 완료된 애만 반환됩니다.
const order1 = () => {
return new Promise((res,rej)=> {
setTimeout(()=>{
res("1번 주문 완료");
},1000)
})
}
const order2 = (message) => {
console.log(message)
return new Promise((res,rej)=> {
setTimeout(()=>{
res("2번 주문 완료");
},3000)
})
}
const order3 = (message) => {
console.log(message)
return new Promise((res,rej)=> {
setTimeout(()=>{
res("3번 주문 완료");
},2000)
})
}
console.log("시작")
Promise.race([order1(), order2(), order3()])
.then((res)=> {
console.log(res)
// ["1번 주문 완료"] 반환
})
Reference
'Tech > [Lang] JS & TS' 카테고리의 다른 글
async, await에 대해서 (0) | 2021.10.14 |
---|---|
클래스 (0) | 2021.10.07 |
상속과 프로토타입 (0) | 2021.10.05 |
함수 호출 메서드 (call, apply, bind) (0) | 2021.09.27 |
스케쥴링 메서드 (setTimeout, setInterval) (0) | 2021.09.24 |