Callback
코드별 우선순위가 다르므로, 순서에 맞게 코드가 실행되려면 async, promise 를 이해해야 한다.
매우 중요!!!
사진 출처
- 실행순서
일반 코드 > Promise(micro) > setTimeOut(regular)
event loop은 stack이 비었을 때 실행된다.
message(callback) queue = microtask queue & regulartask queue
micro가 regular보다 먼저 실행된다. (우선순위 높음)
micro => promise, async
regular => setTimeOut
Warm-up Race
console.log("Horse A");
console.log("Horse B");
console.log("Horse C");
-> a - b - c (synchronous)
Race 1
setTimeout(() => console.log("Horse A"), 1000)
console.log("Horse B")
-> b - a
- 실행 순서
call stack에 setTimeout push
백그라운드 작업을 위해 web api로 전송
1000ms 지나면 작업 완료
callback queue로 이동
call stack에 b push
b 실행
event loop 가 call stack이 비었는지 확인 -> 비었다.
callback queue를 poll 하여 call stack에 push -> a 실행
Race 2
setTimeout(() => console.log("Horse A"), 0)
console.log("Horse B")
-> b - a
- 실행 순서
call stack에 setTimeout push
백그라운드 작업을 위해 web api로 전송
0ms 지나면 작업 완료
callback queue로 이동
call stack에 b push
b 실행
event loop 가 call stack이 비었는지 확인 -> 비었다.
callback queue를 poll 하여 call stack에 push -> a 실행
Race 3
setTimeout(() => console.log("Horse A"), 0);
wait60Seconds();
console.log("Horse B")
-> b - a
js에서 언제나 synchronous 작업이 우선이다. 이벤트 루프는 시간이 얼마나 걸리든 간에 스택에 푸시되는 동기 함수의 종ㄹ류가 있는 동안 비동기작업을 대기열에서 빼지 않는다.
- 실행 순서
call stack에 setTimeout push
백그라운드 작업을 위해 web api로 전송
0ms 지나면 작업 완료
callback queue로 이동
call stack에 wait60Seconds() push
wait() 실행 -> 60초 기다림
call stack에 b push
b 실행
event loop 가 call stack이 비었는지 확인 -> 비었다.
callback queue를 poll 하여 call stack에 push -> a 실행
Race 4
const asyncOperation = fetch('something.com');
asyncOperation.then((resolvedValue) => console.log("Horse A"));
console.log("Horse B")
-> b - a
- 실행 순서
fetch, .then -> Promise
call stack으로 push
web api로 전송
call stack에 b push
b 실행
event loop 가 call stack이 비었는지 확인 -> 비었다.
callback queue를 poll 하여 call stack에 push -> a 실행
Race 5
setTimeout(() => console.log("Horse A"), 0);
const promise = Promise.resolve();
promise.then(() => console.log("Horse B"));
console.log("Horse C")
-> c - b - a
- 실행 순서
call stack에 setTimeout push
백그라운드 작업을 위해 web api로 전송
0ms 지나면 작업 완료
callback queue로 이동
call stack에 promise push
백그라운드 작업을 위해 web api로 전송
callback queue로 이동
call stack에 c push
c 실행
event loop 가 call stack이 비었는지 확인 -> 비었다.
callback queue에서는 promise가 우선순위가 더 높아서 b를 poll 하여 call stack에 push -> b 실행
event loop 가 call stack이 비었는지 확인 -> 비었다.
callback queue에서는 남은 a를 poll 하여 call stack에 push -> a 실행
Race 6
setTimeout(() => console.log("Horse A"), 5)
const promise = new Promise((resolve) => {
setTimeout(() => resolve(), 10)
})
promise.then(() => console.log("Horse B"))
console.log("Horse C")
-> c - a - b
- 실행 순서
call stack에 setTimeout push
백그라운드 작업을 위해 web api로 전송
5ms 지나면 작업 완료
callback queue로 이동
call stack에 promise push
백그라운드 작업을 위해 web api로 전송
10ms 지나서 작업 완료
callback queue로 이동
call stack에 c push
c 실행
event loop 가 call stack이 비었는지 확인 -> 비었다.
callback queue에서는 a가 먼저 끝났기 때문에 a를 poll 하여 call stack에 push -> a 실행
event loop 가 call stack이 비었는지 확인 -> 비었다.
callback queue에서는 남은 b를 poll 하여 call stack에 push -> b 실행
The Final Race
setTimeout(() => console.log("Horse A"), 0);
const promise = fetch("someUrl")
promise.then(x => console.log("Horse B"));
waitFor200ms();
console.log("Horse C");
-> c - b - a
- 실행 순서
call stack에 setTimeout push
백그라운드 작업을 위해 web api로 전송
0ms 지나면 작업 완료
callback queue로 이동
call stack에 promise push
백그라운드 작업을 위해 web api로 전송
100ms 지나서 작업 완료
callback queue로 이동
call stack에 wait() push
wait() 실행 -> 200ms 기다림
call stack에 c push
c 실행
event loop 가 call stack이 비었는지 확인 -> 비었다.
callback queue에서는 a와 b 모두 끝나서 우선순위가 높은 b를 poll 하여 call stack에 push -> b 실행
event loop 가 call stack이 비었는지 확인 -> 비었다.
callback queue에서는 남은 a를 poll 하여 call stack에 push -> a 실행
Bonus Race
async function someFn() {
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("Horse A"), 1000)
});
let result = await promise;
console.log(result);
}
setTimeout(console.log("Horse B"), 0)
someFn();
console.log("Horse C");
-> b - c - a
- 실행 순서
call stack에 setTimeout push
0ms 지나면 바로 작업 완료 -> b 실행
백그라운드 작업을 위해 web api로 전송
callback queue로 이동
call stack에 someFn() push
promise -> 백그라운드 작업을 위해 web api로 전송
1000ms 지나서 작업 완료
callback queue로 이동
call stack에 c push
c 실행
event loop 가 call stack이 비었는지 확인 -> 비었다.
callback queue에서는 a를 poll 하여 call stack에 push -> a 실행
Object
constructor
하나의 객체로 봐도 된다. 생성자도 인스턴스를 만들 수 있다.
function + 첫 글자 대문자
로 쓴다.
ex. function Todo() {}
this
일반적으로 최상위의 root(window)를 가리킨다.
window: js에서 쓰는 모든 기능이 들어있는 것. tree의 root
- 메소드 안에서 쓰이면 해당 객체를 가리킨다.
- 메소드 내에서 regular function (func hi(){}) 에서 사용하면 window를 가리킨다.
-> 객체를 가리키게 하려면?
- 다른 변수에 this를 지정하고 그 변수를 쓴다
- () => {} 를 쓴다.
Class
클래스 내의 메소드를 function
안적고 메소드명()
으로 적는다.
Inheritance
클래스명.prototype.함수이름
새 인스턴스를 만들면 해당 코드만 가리킨다. 인스턴스 안에 해당 코드가 각각 있는게 아니다. 공용의 코드를 가리켜서 사용한다. (동일 주소 공유)