-> 비동기 작업의 성공 혹은 실패, 그리고 return값을 표현하는 객체. 다음과 같이 세 가지 상태 중 하나를 가진다:
const promise = new Promise((resolve, reject) => {
if (some condition is true) {
resolve('You did it!');
} else {
reject('Better luck next time!');
}
});
promise
.then((message) => {
console.log(message); // 성공(resolve)한 경우 실행
})
.catch((error) => {
console.error(error); // 실패(reject)한 경우 실행
});
promise
.then(message => {return something})
.then(something => {return somethingElse})
.then(somethingElse => {return somethingCompletelyDifferent})
.catch(error => {console.error(error)});
$.get('url', function (response) {
parseValue(response, function (id) {
auth(id, function (result) {
display(result, function (text) {
console.log(text);
});
});
});
});
Promise라는 새로운 문법을 사용하지 않고 async 처리를 설계하는 방법 중에는 callback function을 사용하는 방법도 있다. 다만 callback안에 callback을 호출하고, 또 그 안에서 callback을 호출하는 식으로 작업을 이어 주기 때문에 가독성이 떨어지고 유지보수가 어려운 단점이 있다.
let p1 = Promise.resolve(3);
let p2 = 1337;
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('foo');
}, 100);
});
Promise.all([p1, p2, p3]).then(values => {
console.log(values); // [3, 1337, 'foo']
});
async function demonstrateAsyncAwait {
let p1 = await Promise.resolve(3);
let p2 = 1337;
let p3 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve('foo');
}, 100);
});
console.log([p1, p2, p3]); // [3, 1337, 'foo']
}
async keyword를 함수 앞에 붙여 async function으로 만들어 준다. 이 경우 일반 함수가 promise 객체를 return하는 async function이 된다. 이 경우 다른 asynchronous한 함수와 동일하게 .then() 등의 chaining이 가능하다.
async function 내부에 await keyword를 사용할 수 있다. promise 객체 혹은 비동기 함수 앞에 await keyword를 붙여 해당 promise가 이행될 때까지 코드를 멈추고 기다린다.
async/await 문법을 사용하는 경우 try...catch로 error handling을 한다.
async function demonstrateAsyncAwait {
try {
let p1 = await Promise.resolve(3);
let p2 = 1337;
let p3 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve('foo');
}, 100);
});
if (somethingIsWrong) {
throw new Error('Hey, it's an error!');
}
return[p1, p2, p3]; // [3, 1337, 'foo']
} catch(e) {
console.log(e) // 'Hey, it's an error!'
}
}
throw keyword는 에러를 코드 읽는 것을 멈춘다. catch로 throw을 받아서 error handling을 한다. return은 함수가 정상 실행되고 종료되었음을 알리는 키워드로 이후 코드를 정상적으로 실행한다.
-> 비동기 처리를 가능하도록 하는 browser의 기능
Stack
작성한 코드가 stack에 차례로 push되어 실행되고, 실행이 끝나면 pop되어 나온다. 만약 실행될 코드가 비동기문이라면 (setTimeout, ajax(), promise, click event 등) background로 넘겨져서 비동기 실행을 한다.
Callback Queue
background에서 모두 이행되어 나온 실행문은 callback queue에 들어가 stack이 비기를 기다린다. (promise 혹은 thenable method들은 job queue에서 대기한다.)
Event Loop
event loop은 계속 실행되면서 stack에 쌓인 실행문이 있는지 확인하고, stack이 비어 있을 때 callback queue를 확인하여 실행문이 있다면 queue에서부터 pop하고 stack에 push하여 실행되도록 한다.
https://backback.tistory.com/319
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await
https://medium.com/@Rahulx1/understanding-event-loop-call-stack-event-job-queue-in-javascript-63dcd2c71ecd