
여기저기 적어두긴 했는데 확실히 내 머릿속에 정리가 안된 것 같아 미션 코드들을 리팩토링 하면서 적어본다!
동기도 잘 모르는데, 비동기는 무엇일까?
동기는 코드가 (쓰여진 순서대로) 순차적으로 실행되는 것을 말한다. 비동기는 ('비'니까 동기랑 반대겠쥐) 여러개의 작업이 동시에 실행되는 것을 말한다. 간단히 생각하면 둘의 차이는 코드 순서와 실행 순서가 일치하는지 여부로 알 수 있다.
// 간단한 비동기 예제
console.log("ㅎㅇㅎㅇ");
setTimeout(() => {
console.log("안뇽안뇽");
}, 1000);
console.log("ㅃㅇㅃㅇ");
//간단한 동기 예제
console.log("ㅎㅇㅎㅇ");
console.log("안뇽안뇽");
console.log("ㅃㅇㅃㅇ");
동기 예제는 쓰인 순서대로(ㅎㅇㅎㅇ -> 안뇽안뇽 -> ㅃㅇㅃㅇ) 실행되고, 비동기 예제는 쓰인 순서와 달리 (ㅎㅇㅎㅇ -> ㅃㅇㅃㅇ -> (1초) 안뇽안뇽) 요렇게 출력된다.
이때 비동기함수 setTimeout에 감싸진 첫번째 인자(console.log~~)는 콜백함수로, 특정함수가 끝난 뒤 어떤 작업을 실행할 때 (보통은) 익명함수 형태로 들어간다. 여러 작업들이 동시에 진행되기 때문에, 진행 상황을 전달하기 위해서도 콜백함수를 사용합니다.
(++ 콜백지옥 : 위에서 인자로 콜백함수를 넘겨줄 때, 많은 콜백함수들이 연쇄적으로 호출되어 코드의 들여쓰기 수준이 깊어지는 현상을 일컫는다.)
두 개념이 비슷하게 언급되지만 살짜쿵 다르다. Blocking과 Non-Blocking의 차이는 코드의 실행이 다른 코드의 실행을 막는지 여부로 판가름된다. (Blocking은 동기적인 작업에 따라 이후 작업이 막힘)
생각해보자. 코드가 무조건 순차적으로만 실행되면, 하나 끝나고 다음 꺼 하고, 그거 끝나면 또 그 다음꺼 하고.. 작업이 여러개가 있다면 시간이 굉장히 많이 들것 같지 않은가?
물론 '단점'도 존재한다. 코드가 작성된 순서대로 실행되는 것이 아니라서 (나같은 왕초보에게는) 흐름 예측이 어렵다.
= 비동기 작업의 단위(객체)
const promiseEx = new Promise((resolve, reject) => {});
위의 코드는 기본적인 Promise 객체가 사용되는 코드로, resolve는 {}에서 실행되는 executor의 작업이 성공하면 실행되는 콜백함수, reject는 실패하면 실행되는 콜백함수이다. (무조건 성공/실패가 결과로 나타난다.)
비동기 작업이므로 언제 끝날지 모르기 때문에 .then, .catch를 통해 후처리 작업을 시켜준다.
new 연산자가 쓰이면 바로 비동기 작업이 시작된다.function startAsync(age) {
return new Promise((resolve, reject) => {
if (age > 20) resolve(`${age} success`);
else reject(new Error(`${age} is not over 20`));
});
}
(깃블로그에 잘못적었다) ES8(=ECMA Script 2017)에서 처음 도입됨
async function 함수명(){
await 비동기_처리_메서드명();
}
async는 함수 선언시 async function ~~() {} 형태로 Promise 객체를 반환하고, await 키워드는 async 함수 안에서, 뒤에오는 Promise 객체가 끝날 때까지 기다렸다가 비동기 처리가 끝나면 실행되게끔 만든다.await 키워드가 Promise에서 등장하였던 then, catch의 역할을 변수에 담아 처리할 수 있게 해줌 -> 동기적으로 실행되는 코드처럼 예측이 조금은 더 쉬워짐)try-catch문을 통해 처리하면 된다.async 함수로 만들 수 없다.왜 비동기를 설명하면서 엔진 설명을 해야하냐고? 나도 궁금했다!
순수 자바스크립트는 단일 콜스택 구조이기 때문에 비동기가 불가능해 보이나, 브라우저/nodeJS를 활용해 작업을 백그라운드에 요청하여 여러개가 동시에 (비동기!!) 처리되도록 한다.
그래서 우리는 자바스크립트 엔진과 브라우저 환경의 동작 과정을 관찰하며 어떻게 비동기가 실행되는지 제대로 이해해야 한다.
(TMI. nodeJS는 C/C++로 만들어진 libuv(리버브) 라이브러리를 활용해 여섯 단계의 페이즈를 순환하며 콜백 작업을 실행한다. / 이 작동 단계를 더 읽고 작성하고 싶었는데 뇌가 딸려서 fail.. 추후에 추가해보겠음)

(그림은 JS 엔진을 치면 나오는 국룰? 그림인데, 출처를 모르겠다..)
두 개로 구성되어 있다.
Heap 영역
사실 오늘 설명에서 메인이 아니라 간단히 설명하고 넘어간다. 동적인 크기를 갖는 참조값들을 담는 영역이다.
Call Stack 영역
함수가 실행될 때 생성되는 실행 컨텍스트(함수를 실행하는데 필요한 환경/조건을 담은 객체)들이 담긴다.
실행 컨텍스트는 매우 중요한 내용이기 때문에 따로 기록할 예정이지만, 간단히 설명하자면 3가지로 구성된다.
1. Variable Environment: 식별자 정보 수집
2. Lexical Environment: 각 식별자의 '데이터' 추적
(** 어휘적 환경 -> 사전처럼 정보를 구성했다는 의미)
3. This Binding
pop하여 실행한다.Web API로 넘겨져 실행이 끝나면 이벤트 큐에 들어간다.Web API (ex. Ajax, Timeout, ..) 는 참고로 멀티스레드 (병렬실행) ** 이벤트 = 어플리케이션 내에 발생한 응답 가능한 사건
(ex. 사용자가 어떤 버튼을 클릭)
= 자바스크립트 엔진과의 환경 연동을 위해!
(자바스크립트가 구동되는 환경에서 여러 개의 스레드가 연동되는데, 이 스레드들의 코드를 스케줄링하고 실행시킴)
코어 자바스크립트
깃블로그 글/아래에 참고 링크 있슴다
깃블로그 글2/아래에 참고 링크 있슴다
async-await 이해
좋은 글 감사합니다. 자주 방문할게요 :)