JS엔진 되기 2일차

송은우·2022년 3월 27일
0

살려줘

비동기 : 동시의 개념이 아님. 순서의 문제

한 번 비동기는 영원한 비동기. async/await은 무조건 영원히 비동기
비동기를 동기로 바꾸려는 노력을 전혀 하지 않기

콜백은 비동기랑 관계 없음. 비동기 콜백은 비동기, 동기 콜백은 동기다.

비동기는 선언 지도, 호출스택만으로 제대로 분설을 할 수가 없어짐.

이벤트 루프
백그라운드와 큐 2개(매크로 태스크, 마이크로 태스크)
로 설명하기 편함. 99%에 가까운 것은 맞지만, 아주 특수한 이상한 코드는 틀릴 수 있음

함수 자체가 비동기인지, 동기인지는 무조건 찾아보아야 함.
promise인지 아닌지 같은 것들은 모두 다 검색하기

setTimeout(()=>{
	console.log('a');
},0);
setTimeout(()=>{
	console.log('a');
},1000);
setTimeout(()=>{
	console.log('a');
},2000);

이 코드가 있을 때 단순하게 위에서부터 분석을 하는 그 방식대로 하되, 비동기 함수를 만났을 때 background에다가 추가를 함.(zerocho님이 만든 개념) 운영체제나, JS엔진과 오히려 유사하지 JS의 개념이라고 보기는 조금 그럼 언어가 같을 필요도 없음
그렇기에, 백그라운드 안에 있는 것들은 동시에 들어갈 수 있음.
백그라운드에 들어갈 수 있는 것들은 따로 알아야 됨. 예를 들면 setTimeout의 timer, promise, process.nextTick, ajax 요청
타이머 3개를 동시에 시간초를 세어 줘야 함.

백그라운드에 간 코드는 task queue를 거쳐서, 호출 스택으로 올라감. Macro 에 있는 것에 queue
이벤트 루프는 queue에 있는 함수를 호출 스택으로 옮겨줌.

비동기도 사실 순서를 조절해준다고 생각하면 동기랑 큰 차이가 없게 느껴질 수 있음

암기하기!
Micro에 들어가는 것만 암기. promise, process.nextTick만 암기하기
비슷한 시기에 micro queue가 먼저 호출 스택으로 가고, macro는 그 다음에 감. 시간 차이가 있으면 먼저 들어간 것부터 나옴

한 번 비동기는 영원한 비동기기에 콜백헬

const p=new Promise((resolve),reject)=>{
	console.log("제일 먼저");
	setTimeout(()=>{
    	a=5;
    	console.log(a);
    	resolve(a);
    },0);
});

promise는 실행은 바로 하되, 값은 나중에 받는다!
then 과 함께 분석하는 것
되게 중요한 것 promise안에 저 부분은 동기임.
이런 것들을 잘 생각해야 됨
then 은 event listener 느낌으로 바라보는 것이 가장 좋음.
여기서는 당연히 then 도 백그라운드에 등록되겠다는 느낌
꼭 catch가 제일 마지막일 필요는 전혀 없음. then catch then catch로 가도 됨
마지막 캐치는 다 담당해야되기에 일이 많아짐
try, catch문을 나누는 것은 하는데 왜 지금까지 catch then catch를 하지는 않았을까?

promise then 을 볼때 promise를 return하면 resolve를 기다리고, 일반 값을 리턴하면 그냥 바로 다음 함수로 인자를 가져감

const a= await 1
const b= Promise.resolve(1);
이런 것들은 그냥 a=1, b=1로 들어감


이거를 promise로 바꿀 수 있을까?

promise.resolve(1)
.then((a)=>{
	console.log(a);
    console.log('hmm');
    return null;
})
.then(()=>{
	return Promise.resolve(1);
})
.then((b)=>{
	console.log('b',b);
})

만약 await 1이 아닌 경우에는 그냥 써도 됨

axios.get().then 같은 느끼믕로 시작하는 것도 가능함

그냥 암기 해버리기. await은 then이다.
async는 오른쪽에서 왼쪽으로, promise에서는 왼쪽에서 오른쪽으로 가야 됨. null부분을 집중해서 잘 보기
여기서 1:1 대응은 아니라는 것은 기억해야 됨.
만약 마지막이 a+b다 라고 했을 경우 애매해질 수 있음

당연히 제대로 하려면 뭐 기존 값을 다 args로 return 하고, return한 값을 처리하고 하는 방법으로 해야 되기는 함.

출처 zerocho 유튜브
async함수는 1번째 await전에 끝난다고 생각해야 분석이 됨. 거기까지가 동기

promise, async도 각자 앞부분은 동기 처리가 된다는거 명심하기
async라도 무조건 await만으로 할 수 있는 것이 아니라 promise와 같이 쓰이는 경우는 Promise.allSettled같은 것으로 동시에 실행해야 될 때.

await를 빼고 그냥 변수에 담아두면 일단 실행은 다 됨. 그리고 제일 마지막에 Promise.allSettled로 처리하는 과정이 있으면 대기시간이 훨씬 줄어들어서 좋은 코드가 됨

바벨에서는 async를 generator yield로 바꿈
싫다면 즉시 실행 함수로 미리 변수 선언했던 부분을 빼버리는 방법으로 처리가 불가능 하지는 않음 이러면 args로 받고 넘기는 부분이 없어지긴 하지만 generator yield로 처리하는 것 대신 가능은 하지만 왜?

requestanimationframe 같은 경우도 settimeout이나, document.onclick이든 다 백그라운드에 등록을 시킨다고 생각하고, 실행 됬을 때 Macro가는지, micro가는지 그때마다 볼 필요는 있음

백그라운드에 fetch가 동시에 진행될 수 있는 내부 수량은 정해져 있을 것. 아마 12개인가 같은 숫자가 있음

map 같은 것에서 promise를 보내면, 순서 보장이 안됨 map 안에서 await으로 처리하더라도, 절대로 순서대로 처리되지 않음.

for 문으로 처리해야 됨. for of 같은 것은 순서대로 잘 되지만 map은 다름 이런 처리가 매우 중요함

클로져!

클로저 => 스코프, 비동기, var (쓰레기)
클로져가 문제다X
클로져를 사용해서 해결하는 문제
for문과 비동기를 함께 사용하면 종종 발생

function a(){
	for(var i=0;i<5;i++){
    	setTimeout(()=>{
        	console.log(i);
        },i*1000);
    }
}

5 5 5 5 5 라고 출력이 되는 이 거지같은 현상
해결은 let으로 바구면 해결됨
let 나오기 전에는 즉시 실행 함수로 setTimeout으로 바꿔서 처리하는 것이 가능함.

var, for, 비동기의 환상의 콜라보
해결법은 var 유지해야 할 경우는 iife(즉시 실행함수) 로 클로저 생성. var=>let

왜 55555가 나오는지

보면 동기 부분과 아닌 부분 고려를 잘 해야함.
동기 부분에서 이미 i는 5가 되어 버림.
그래서 background에 들어간 시간은 제대로 작동하지만, 바깥에 있는 i가 계속 5로 읽어지는 문제가 생김

j로 감싸면 저런게 된다. 라는 거 느낌

우리는 var만 안 쓰면 좀 살만하다
선언 지도를 바탕으로 보면 바로i를 바라보기에 저렇게 문제가 되지만 중간에 j라는 변수가 생겼기에 0,1,2,3,4,5 를 봤을 때 대입이 되고, 변할 일이 없기에, 그냥 그대로 남아 있게 됨


i를 바라볼 때 자기 바로 바깥에 있었던 부분은 그대로 가져간다는 느낌
캡처 타이밍의 부분을 수정한 것
var의 경우에는 function 보다 바깥 scope를 참조함
function a의 스코프는 1개고, for문의 스코프는 5개. a스코프에서 i는 0=>5로 정해진 거고,
let문은 애시당초 a스코프를 참조할 필요가 없으니까 for문의 scope만으로 해결이 됨 5번의 스코프가 되니까

function a(){
    setTimeout(()=>{
        console.log("a");
    },0)
}
function b(){
    a();
    return Promise.resolve()
    .then(()=>{
        console.log("b");
    })
    .then(a);
}
b();

이렇게 됬을 때 어떤 결과가 나올까?
b a a 로 결과가 나옴

profile
학생의 마음가짐으로 최선을 다하자

0개의 댓글