Block / NonBlock , Sync / Async
이번에는 JS에서 가장 중요하면서 어렵고 헷갈리는 개념 중 하나인 "Block / Non - Block", "Sync / Async"를 알아보겠습니다!
머리로는 이해해도 설명해보라고 하면 뭐라 설명할 수 없는 그런....
저도 100% 이해가 어려워 계속해서 코드를 작성해 보며 이해해 나가고 있습니다.
파이팅!!
Block / NonBlock
Block
- 현재 작업이 다른 작업을 실행을 차단하는가
- 제어권을 기준으로 함.
const fs = require('fs');
const data = fs.readFileSync('./file_path');
console.log('파일 읽기 완료', data);
// data에 파일이 읽힌 후, '파일 읽기 완료'가 출력된다.
- 특정 작업을 실행할 때 제어권을 완전히 넘기는 방식
- 제어권이 넘어갔기 때문에, 다른 작업을 진행할 수 없음
Non Block
- 특정 작업 실행 시 제어권을 넘겨 실행 후 즉시 돌려받는 형태
- 작업이 진행되는 동안 백그라운드에서 다른 작업이 진행
- 제어권을 돌려받기 때문에 다른 작업을 수행할 수 있음
Sync / Async
- 현재 작업과 다음 작업이 순서 대로 실행 되는가?
- 결과를 기준으로 함.
Sync
- 특정 작업이 완료될 때까지 기다리는 방식
- 제어권은 특정 작업 실행 이후 즉시 돌려받는 형태.
- 사실상 제어권이 넘어오면서 결과도 같이 나온다.(Block / Async)
즉, 제어권은 즉시 돌려받지만 작업이 완료되어 결과가 나올 때까지 다른 작업을 수행하지 않음.
function doWorkSync() {
const start = Date.now();
while (Date.now() < start + 10000);
console.log('동기 작업 완료');
}
console.log('작업 시작');
doWorkSync();
console.log('다음 작업');
//작업 시작
//현재시간 + 10초간 '동기 작업 완료'가 계속 출력됨.
//다음 작업
이 처럼 doWorkSync()가 끝날 때 까지 기다린 후 console.log(’다음 작업’) 이 실행됩니다.
Async
- 특정 작업에 대한 진행 상황, 결과 처리를 제어권이 신경 쓰지 않음.
- 비동기 직업 이후 결과 처리를 해야 한다면?
- 기존 작업 진행하고 있는 게 있다면 처리 후 진행
function doWorkAsync() {
setTimeout(() => {
console.log('비동기 작업 완료');
}, 1000);
}
console.log('작업 시작');
doWorkAsync(); //작업이 끝나고 결과가 나왔어도 call stack이 비어있지 않아서 기다림(call stack이 완전히 비어있을 때 결과 출력)
console.log('다음 작업');
//작업 시작
//다음 작업
//비동기 작업 완료
Combination
Block | Non - Block | |
Sync | Block / Sync | Non - Block / Sync |
Async | Block / Async | Non - Block / Async |
Block / Sync
- 제어권과 결과 처리 순서가 동일한 방식.
Non - Block / Sync
- 제어권은 실행 즉시 반환
- 지속적인 결과처리 관찰
- 결과가 완료되었을 때 해당 처리 진행 (call stack이 비어있는 경우)
Block / Async
- 제어권은 실행 즉시 반환
- 결과 처리가 나올 때까지 다른 작업을 하지 않음 (Sync 작업과 같음)
- 잘못된 코딩의 예시이다
Non-Block / Async
- 실행 즉시 제어권 반환
- 결과에 관계없이 자신의 작업 진행
- 결과처리를 요청받으면 현재 작업을 마무리하고 결과 처리 작업 진행
Excution Context와 비동기 처리
- call stack에 비동기 setTimeout() context push
- WebAPI에게 setTimeout context 전달
- 비동기 작업 진행(1초 대기)
- Func b context가 call stack에 push 후 진행
- Func c context가 call stack에 push 후 진행
- WebAPI가 1초가 지난 후 setTimeout context를 TaskQueue로 전달
- EventLoop가 call stack과 TaskQueue를 지속적으로 감시하며 call stack이 비어있을 때, TaskQueue에 있는 setTimeout context를 call stack으로 전달
- setTimeout context call stack에 push후 진행
const a = () => {
console.log("a");
return d();
};
const b = () => {
console.log("b");
};
const c = () => {
setTimeout(() => {
console.log("c");
}, 1000);
};
const d = () => {
setTimeout(() => {
console.log("d");
}, 0);
};
c();
a();
b();
//출력
//a
//b
//d
//c
'Frontend' 카테고리의 다른 글
<Frontend> JavaScript / 비동기 처리 (1) | 2024.04.03 |
---|---|
<Frontend> JavaScript / 모듈 시스템 (Module) (0) | 2024.03.27 |
<Frontend> JavaScript / This (0) | 2024.03.27 |
<Frontend> JavaScript / 객체(Object) (0) | 2024.03.26 |
<Frontend> JavaScript / 실행 컨텍스트 (0) | 2024.03.26 |