비동기 Asynchronous

const_yang·2021년 11월 15일
0

TIL

목록 보기
5/14
post-thumbnail

개념

  • Blocking: 한 작업이 완료되기 전까지 다른 작업을 진행하지 못하는 개념
  • 동기적 (synchronous): 한 작업의 완료 시점과 다른 작업의 시작 시점이 같은 개념

이런 불편함을 해소하기 위해,

비동기적(asynchronous)으로 작동하는 런타임이 개발되었다. 아래와 같은 작업에 유용하다.

  • 백그라운드 실행, 로딩 창 등의 작업
  • 인터넷에서 서버로 요청을 보내고, 응답을 기다리는 작업
  • 큰 용량의 파일을 로딩하는 작업

문법

세 가지 문법 중 하나로 비동기 흐름을 구현할 수 있다.

callback, promise, async/await

개념 정리

  • blocking / non-blocking
  • synchronous / asynchronous
  • callback 함수 전달 방법
  • method chaining(Array의 map, filter 등)

학습 목표

  • 어떤 경우에 중첩된 callback이 발생하는지 이해할 수 있다.
  • 중첩된 callback의 단점, Promise의 장점을 이해할 수 있다.
  • Promise 사용 패턴을 이해할 수 있다.
    • resolve, reject의 의미와, then, catch와의 관계를 이해할 수 있다.
    • Promise에서 인자를 넘기는 방법을 이해할 수 있다.
    • Promise의 세 가지 상태를 이해할 수 있다.
    • Promise.all 의 사용법을 이해할 수 있다.
  • async/await keyword에 대해 이해하고, 작동 원리를 이해할 수 있다.
  • Node.js의 fs 모듈의 사용법을 이해할 수 있다.

고차함수

  • 다른 함수를 인자로 전달 받는 함수: 인자로 전달되는 함수를 Callback 함수라고 한다.
  • 다른 함수를 리턴하는 함수: 커리 함수라고 한다.
💡 '커리 함수' 용어를 사용할 경우 '고차 함수'는 함수를 인자로 전달 받는 함수를 의미한다.

비동기호출

전화: 동기적, blocking (작업이 멈추고 전화를 받아야 한다)

문자: 비동기적, non-blocking (하던 작업을 멈추지 않고 나중에 문자를 확인할 수 있다)

💡 함수의 실행을 작성자가 control 할 수 있도록 한다는 것이 비동기적으로 작동하도록 한다는 것과 같다고 볼 수 있다.

비동기를 왜 배워야 하나?

jquery의 ajax 통신과 같이 원하는 데이터를 서버에서 받아오는 방식의 앱을 개발할 때 유용하다. 비동기없이 데이터를 가지고 온다고 했을 때, 데이터가 수집되기 전까지 아무것도 하지 못하는 오류가 발생할 수 있기 때문이다.

Callback으로 어떻게 비동기를 구현할 수 있을까?

어떤 함수의 인자로 들어오는 콜백 함수는 결국 어떤 함수 내에서만 실행이 된다.

비동기 API가 있다고 하자. 해당 API에 콜백함수를 넣어 준다. 해당 비동기 API 앞뒤로 다른 함수가 실행되고 있다고 한다면, 해당 다른 함수가 먼저 실행이 되고 비동기 API 내의 콜백함수가 실행된다. 이로써 비동기적인 구현을 할 수 있다.

// sync
console.log(1);
var data = fs.readFileSync('data.txt', 'utf8');
console.log(data);
// 실행 순서 => 1, 'data.txt' 파일 내 내용

// async
console.log(2);
var data = fs.readFile('data.txt', 'utf8', function (err, data) {
  console.log(3);
  console.log(data);
})
console.log(4);
// 실행 순서 => 2, 4, 3, 'data.txt' 파일 내 내용 
// (node 비동기 모듈 앞뒤에 있는 함수가 실행이 끝나기 전까지 모듈을 실행하지 않는다.)

Event Loop

JS 엔진의 구성은 Memory Heap, Call Stack, Web APIs, Callback Queue 등으로 이뤄져있다.

  • Memory Heap: 메모리 할당이 일어난다.
  • Call stack: 실행 코드의 한 줄 단위로 할당된다.
  • Web APIs: 비동기처리를 담당한다(Node에서는 백그라운드로 설명된다)
  • Callback Queue: 비동기처리가 끝난 후 실행되어야 할 콜백 함수가 차례대로 할당(Task Queue, Event Queue 등 다양한 형태)

<출처: https://poiemaweb.com/js-event>

  • Event Loop

아래 코드를 실행한다고 하자.

console.log('first')

setTimeout(function () {
    console.log('second')
}, 1000);

console.log('third')

1) console.log(‘first’)가 Call stack에 추가된다.

2) console.log(‘first’)가 화면에 출력된 뒤, Call stack에서 제거된다.

3) setTimeout API가 Call stack에 추가된다. 그리고 Web APIs에 옮겨지고, Call stack에서 제거된다.

4) console.log('third')가 Call stack에 추가된다. (Web APIs에 옮겨진 setTimeout은 1초 뒤 callback으로 전달한 익명함수 "(function () {console.log('second')}"가 Callback Queue에 추가된다)
5) console.log(‘third’)가 화면에 출력된 뒤, Call stack에서 제거된다.

6) Event Loop로 Call stack이 비어있는지 계속 확인하다 console.log(‘third’)가 제거되면 Callback Queue에 담겨있던 익명함수를 Call stack에 담고 함수를 실행한다 (console.log('second'))

7) console.log('second')가 화면에 출력된 뒤, Call stack에서 제거된다.

0개의 댓글