나 이것도 몰랐네..
자바스크립트 1 - 동기/비동기 본문
동기와 비동기
동기(Synchronous)
- 요청이 들어오면 스레드(Thread)에서 순차적으로 작업을 수행하고, 해당 작업이 수행중이면 다음 작업은 전 작업이 끝날 때 까지 기다렸다가 수행
※ 스레드(Thread) : 프로세스 내에서 실행되는 흐름의 단위를 의미
비동기(Asynchronous)
- 요청이 들어오면 스레드에서 이전 요청에 의한 작업이 끝나지 않아도 계속 요청을 받음, 이 후 작업 종료 이벤트 발생 시, 해당 요청을 처리함
JavaScript의 동작 원리
JavaScript는 Synchronous이고, Blocking이며, Single-threaded한 언어
- Single-threaded란, 하나의 프로그램은 하나의 코드만 실행할 수 있음을 의미
- 싱글 콜 스택(call stack)을 의미
- JavaScript의 엔진은 Memory Heap과 Call Stack으로 구성
- Memory Heap : 변수와 객체의 메모리 할당을 담당하는 곳
- Call Stack : 함수가 호출되면 쌓이는 곳, 함수가 쌓이는 순서와는 반대로 실행됨
- Call Stack은 선입선출로 나가게 됨
따라서 JavaScript는 동기 언어이다!
JavaScript에서 비동기적 처리 방식
- 브라우저에서의 자바스크립트 실행 환경에서는 DOM 조작이나 AJAX와 같은 비동기 처리를 위한 WEB API를 제공
- 또한 이를 제어하기 위해 이벤트 루프(Event loop), 이벤트 큐(Callback Queue 혹은 Task Queue)가 존재
1) Callback 함수
- 다른 함수가 실행을 끝낸 뒤 실행되는 함수를 말함
- 자바스크립트의 블록킹을 방지하여 싱글 스레드가 논블록킹으로 동작하도록 함
- 함수의 처리 순서를 보장하기 위해 함수를 중첩해 사용하는 경우가 발생해 콜백 지옥이 발생하고, 그로 인해 에러 처리가 힘들다는 단점이 존재
2) Promise
비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냄
- 프로미스가 생성된 시점에는 알려지지 않았을 수 있는 값을 위한 대리자로, 비동기 연산이 종료된 이후에 결과 값과 실패 사유를 처리하기 위한 처리기를 연결할 수 있음
- 최종 결과를 반환하는 것이 아닌, 미래의 어떤 시점에 결과를 제공하겠다는 약속을 반환함
promise는 다음 중 하나의 상태를 가짐
- 대기(pending) : 이행하지도 거부하지도 않은 초기 상태
- 이행(fulfilled) : 연산이 성공적으로 완료됨
- 거부(rejected) : 연산이 실패함
- 이행이나 거부될 때, 프로미스의 then 메서드에 의해 대기열에 추가된 처리기들이 호출
- 성공 값(Resolve)의 경우, then 사용하면 결과를 return
- 실패 값(Reject)의 경우, catch로 연결
- Finally 메서드를 통해 프로미스를 처리한 후 호출할 함수를 예약할 수 있음
3) Async / await
- 프로미스를 기반으로 동작하지만, then/catch/finally 후속 처리 메서드에 콜백 함수를 전달해 비동기 처리 결과를 처리할 필요없이 동기 처리처럼 프로미스를 사용할 수 있음
- async 함수는 async 키워드를 사용해 정의하며 언제나 프로미스를 반환함
- async 함수가 명시적으로 프로미스를 반환하지 않더라도 async 함수는 암묵적으로 반환값을 resolve 하는 프로미스를 반환
- await 키워드는 다음 실행을 일시 중지 시켰다가 프로미스가 해결된 후 다시 실행하기 때문에 모든 프로미스에 await 키워드를 사용하는 것은 주의해야 함
- 여러 비동기 처리가 서로 연관없이 개별적으로 수행되는 비동기 처리일 때는 일일이 키워드를 적는 것이 아닌 아래와 같이 처리해야 함
async function foo() {
const res = await Promise.all([
new Promise(resolve => setTimeout(() => resolve(1), 3000)),
new Promise(resolve => setTimeout(() => resolve(2), 2000)),
new Promise(resolve => setTimeout(() => resolve(3), 1000)),
]);
console.log(res); // [1, 2, 3]
}
foo();
- async / await에서 에러 처리는 try / catch 문을 사용할 수 있음
- async 함수 내에서 catch 문을 사용해서 에러 처리를 하지 않으면 async 함수는 발생한 에러를 reject하는 프로미스를 반환
promise와 async/await의 차이점
- 에러 핸들링
- Promise의 경우 catch()를 통해 에러 핸들링이 가능하지만 Async / await의 경우 에러 핸들링 기능이 없어 try-catch()문을 활용해야 함
- 코드 가독성
- Promise의 경우 then()의 중첩으로 인해 코드가 길고 들여쓰기 중첩이 심해질 수 있으나, Async / await의 경우 동기 코드처럼 읽히도록 가독성이 좋음
'언어 > 자바스크립트' 카테고리의 다른 글
자바스크립트 5 - 이벤트 (0) | 2024.04.15 |
---|---|
자바스크립트 4 - 스코프와 클로저 (0) | 2024.03.29 |
자바스크립트 3 - 데이터 타입 및 복사 (0) | 2024.03.29 |
자바스크립트 2 - 변수 (0) | 2024.03.29 |
자바스크립트란? (0) | 2024.03.20 |