-
동기와 비동기, 자바스크립트에서 비동기 처리가 가능한 이유, 비동기 프로그래밍CS지식 2023. 11. 11. 15:53
동기와 비동기
- 동기 처리: 반드시 코드가 작성된 순서대로 진행된다.
장점: 실행 순서 보장
단점: 블로킹 발생, 하나의 작업이 너무 오래 걸리게 되면 오래 걸리는 하나의 작업때문에 모든 작업이 올스탑되어 처리속도가 매우 느려져 성능 상에 문제가 발생하게 된다.- 비동기 처리: 현재 실행중인 코드가 완료되지 않더라도 기다리지 않고 다음 코드를 실행하는 방식이다.
실행중인 태스크가 종료되지 않은 상태라 해도 다음 태스크를 곧바로 실행한다.
이벤트 핸들러, setTimeout, setInteraval, HTTP 요청은 비동기 처리 방식으로 동작한다.
장점: 블로킹 발생 X
단점: 실행 순서 보장 X그런데 싱글스레드인 자바스크립트에서 어떻게 비동기 처리가 가능할까?
자바스크립트 엔진은 싱글스레드라서 실행 대기 중인 태스크가 쌓이는 콜스택(실행컨텍스트 스택)을 하나만 가지고 있다. 최상단부터 하나씩 실행되기 때문에 한번에 하나의 태스크만 실행 가능하다. 동시에 여러개의 함수를 실행할 수 없다!
브라우저 내부에는 자바스크립트 엔진의 싱글스레드의 한계를 극복하기 위해 비동기로 동작할 수 있도록 web APIs, 콜백큐, 이벤트 루프를 제공한다. 즉, 브라우저 내부에는 자바스크립트 엔진을 뿐만아니라 이벤트 리스너, setTimeout 같이 기다림이 필요한 비동기 함수들이 들어가는 Web APIs, 그러한 비동기 함수들이 차례차례 쌓이는 콜백큐, 콜스택이 비워질 때를 체크해서 콜백큐에 대기중인 비동기 함수를 콜스택에 보내주는 이벤트 루프가 있다. 이벤트 루프는 이 작업을 반복(loop)하고 이러한 브라우저의 동작원리 덕분에 자바스크립트가 싱글 스레드 언어여도 비동기 작업을 처리할 수 있도록 해주는 것이다.
비동기 프로그래밍이란?
비동기적으로 실행되는 것을 동기적으로 코딩하는 방법이다.
비동기 프로그래밍이 중요한 이유는
서버에 요청한 데이터가 도착하기 전에도 사용자와의 인터랙션을 유지할 수 있으므로 사용자 경험을 향상시킬 수 있게 된다.예를 들어 이미지가 렌더링되는 동안 사용자는 또 다른 작업을 할 수도 있다.
비동기 프로그래밍 방법
1. Callback 함수 ex) 이벤트리스너, setTimeout
정의: 함수의 파라미터로 들어가는 함수
용도: 순차적으로 실행하고 싶을 때
단점
: 여러개의 비동기를 처리할 때 콜백지옥 발생
: 가독성 저하
: 에러핸들링 어려움
: 함수 안에서만 결과값 처리와 결과값을 알 수 있어서 매번 비동기함수를 싱행해야함
2. Promise 객체 (ES6)
비동기 작업의 결과값이 Promise 객체에 저장되기 때문에
로직 밖에서도 .then 메소드를 통해 저장되어 있는 성공(resolve 반환), 실패(reject 반환) 결과값을 원하는 때에 사용할 수 있다.성공 시, then 메소드 실행
실패 시, catch의 메소드 실행
→ 하나의 catch만으로 상위에 체이닝되어있는 어떤 함수에서 에러가 나더라도 에러 핸들링이 가능하다.
성공 실패 여부 상관없이, finally 메소드 실행
→ 무조건 실행되어야 할 로직을 짜는 곳에 사용된다.- Promise의 3가지 상태
pending : 비동기 처리 미완료(ful,rej 이전)
fulfilled: 비동기 처리 성공: resolve 호출, then에 비동기 처리 결과를 전달
rejected : 비동기 처리 실패, 오류: reject 호출, catch에 에러 결과를 전달- 단점: 지나친 then의 사용은 콜백지옥과 비슷한 문제가 발생한다.
3. async/awail (ES8)
좀 더 쉽고 직관적으로 Promise를 이용할 수 있다. 가독성이 좋다.
Promise의 후속처리메소드 없이, 마치 동기적으로 Promise를 사용할 수 있다.
- 사용법
- 함수 앞에 async를 붙혀주면 그 함수는 자동적으로 Promise를 리턴하는 비동기 처리 함수가 된다.
- await 키워드는 promise가 resolve한 결과값을 반환한다.
- await을 비동기 함수의 호출 앞에 붙히면 await이 붙은 함수의 호출은 뒤에있는 함수가 끝나기 전까지 아래에 있는 코드를 수행하지 않는다.
- Promise의 후속처리메소드 없이, 마치 동기적으로 Promise를 사용할 수 있다.
- await는 실패하면 에러가 나고 코드가 멈추기때문에 try/catch를 사용하여 에러 처리를 할 수 있다.
- then과 달리 어떤 지점에서 에러가 발생했는지 쉽게 찾을 수 있다.
'CS지식' 카테고리의 다른 글
리액트 렌더링 최적화 (2) 2023.11.14 주소창에 google.com을 입력하면 일어나는 일 (0) 2023.11.14 리액트의 재선언, Virtual DOM 동작원리, Diffing 알고리즘 (0) 2023.11.11 호이스팅, 호이스팅 원인, 호이스팅 종류 (0) 2023.11.05 실행컨텍스트, 호이스팅, 스코프체이닝 (feat. 테코톡 하루님) (2) 2023.11.04