1. 탐구
Mission
1. delay함수 만들기
-
while문 활용
function delay(ms) { const start = Date.now(); while (Date.now() - start < ms) { } } console.log(1); delay(1000); console.log(2)while문을 활용하여 물리적으로 시간이 흐르도록 했다. while문은 비동기적으로 실행되지 않고, call stack에서 처리가 되기 때문이다.
-
Promise + setTimeout 활용
// function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } ( async function () { console.log(1); await delay(1000); console.log(2) } )()Promise객체를 생성하여, callback함수로 setTimeout을 넣어주었다.
2. n초마다 함수 실행하는 함수 만들기
let interval = setInterval(() => {
console.log(num);
}, 500)
3. Promise 객체들을 만들고, 모든 Promise 객체가 resolve되었을 때, 다음 문장을 실행하기
const promiseMaker = (ms) => new Promise(resolve => setTimeout(() => {
console.log(ms)
resolve()
}, ms)); // Promise 객체 생성기
const promise1 = promiseMaker(1000); // 1초의 setTimeout Promise객체를 리턴하는 Promise 객체
const promise2 = promiseMaker(2000);
(
async function () {
console.log(1)
await Promise.all([promise1, promise2]); // Promise.all은 Promise객체를 배열로 전달받아 병렬로 처리한다.
console.log(2)
}
)()
출력 : 1, 1초 후 1000, 2초 후 2000과 2
다양한 상황
-
setTimeout
console.log(1) setTimeout(() => { console.log(2) }, 1000) console.log(3)1, 3이 먼저 출력되고, 1초 후에 2가 출력된다. 2는 node.js api에 넘어가, 비동기적으로 처리가 되고, callback queue에 넘겨지기 때문이다.
-
setInterval로 일정 간격으로 실행하고, 중단하기
const num1 = numberMaker(); let interval; startButton.addEventListener('click', () => { interval = setInterval(() => { num1.addNumber(); console.log(num1.getNumber()); }, 500) }) stopButton.addEventListener('click', () => { clearInterval(interval) }) -
Promise 생성기
const promiseMaker = second => () => new Promise((resolve) => setTimeout(resolve, 1000 * second)) const promise1 = promiseMaker(1); // promiseMaker는 Promise 객체를 반환한다. const promise2 = promiseMaker(2); ( async function () { console.log(1); await promise1(); console.log(2); await promise1(); console.log(3); } )()- Promise를 여러 번 사용하려면 함수로 반환되어야 한다
const promise1 = new Promise(resolve => setTimeout(resolve, 1000));
(
async function () {
console.log(1);
await promise1;
console.log(2);
await promise1;
console.log(3);
}
)()
위를 실행하면 1이 출력되고, 1초 후 2와 3이 함께 출력된다.
하지만 아래와 같이 함수로 Promise 객체를 생성하면 1 > 2 > 3이 순차적으로 실행이 된다.
const promise1 = () => new Promise(resolve => setTimeout(resolve, 1000));
(
async function () {
console.log(1);
await promise1();
console.log(2);
await promise1();
console.log(3);
}
)()
왜냐하면, 첫 번째 코드에서 promise1은 하나의 객체이기 때문이다. Promise객체를 생성하고, 처음 await promise에서 해당 Promise의 setTimeout이 실행된다. 그 이후에 다시 await되면, 이미 resolve된 상태이므로 추가적인 대기 시간 없이 실행된다.
하지만 두 번째 코드에서는 promise1()을 실행했을 때 해당 Promise객체가 생성이 된다. Promise객체 앞에 await키워드가 있으므로, 끝날 때까지 기다렸다가 순차적으로 처리가 된다.
2. 고민
Promise를 사용하지 않으면, setTimeout을 활용할 수 없을까? axios같은 경우에도, Promise객체를 만드는 걸까?
❓ Promise
: 비동기 작업이 맞이할 미래의 완료 또는 실패, 그 결과 값을 나타낸다.
pending, fulfilled, rejected 세 가지 상태가 있다.
Promise가 아니라면, callback함수를 황요할 수 있을 것이다.
❓ await
await문은, Promise를 기다리기 위해 사용된다. 그리고, async 함수 내부에서만 사용할 수 있다.
await문은 Promise가 fulfill되거나 reject될 때까지 async 함수의 실행을 일시 정지하고, Promise가 fulfill되면 async함수를 일시 정지한 부분부터 실행한다. 이 때 await문의 반환값은 Promise에서 fulfill된 값이 된다.