자바스크립트의 비동기 동작

Deagwon Bu·2021년 8월 2일
0
post-thumbnail

웹을 공부하다보면 axio, promise, callback 등의 여러 기능을 공부하게 된다. 또한 글을 조금만 찾아보면 이러한 기능은 "비동기"라는 동작과 관련되어 있다는 사실을 알 수 있다. 이번 포스트에서는 이 "비동기"가 무엇이고 javascript에서 "비동기"작업을 어떻게 구현하는 지 얕게 알아본다.

비동기 Asynchronous vs 동기 Synchronous

작업을 하는 주체와 대상이 2개 이상인 상황에서 비동기와 동기를 구분한다.

  • 비동기 - Asynchronous
    • 작업들의 시작/종료 시점 및 순서를 결정할 수 없는 상황
    • 작업 주체의 작업 시작/종료 순간이 서로 일치하지 않는 상황
  • 동기 - Synchronous
    • 작업들의 시작/종료 시점 및 순서를 결정할 수 있는 상황
    • 작업 주체의 작업 시작/종료 순간이 서로 일치하는 상황

Block vs non-Block

작업의 주체와 대상이 2개 이상인 상황에서 Block과 non-Block을 구분한다.

  • Block
    • 하나의 작업자가 다른 작업자에게 보낸 요청이 돌아 오기 전 까지 대기하는 상황
  • non - Block
    • 하나의 작업자가 다른 작업자에게 보낸 요청이 돌아 오기 전에 다른 작업을 하는 상황

비동기, 동기, block, non-block

실제로 비동기와 동기를 구분하는 기준과 block vs non-block을 구분하는 기준은 다르다. 따라서 다음의 조합이 가능하다.

  • 비동기 - block
  • 비동기 - non-block
  • 동기 - block
  • 동기 - non-block

JS의 비동기 동작

배경

기초적인 프로그래밍에서는 대부분 함수의 시작과 종료를 논리적으로 예측할 수 있다.
이처럼 작업들의 시작/종료 시점 및 순서를 결정할 수 있는 작업들을 동기 작업이라고 한다.
예를 들면

	1) A = 1 
	2) B = A + 1
	3) C = A + B

를 수행하기 위해서는 1) -> 2) -> 3)을 순차적으로 수행해야 한다.

하지만, 웹 프로그래밍에서는 그렇지 못한 경우가 존재한다.

	1) Client가 api server에 데이터 요청을 보내고 응답을 받음.
	2) Client는 소수 1000개를 구하는 연산을 함.
	3) Client는 api server에서 받은 데이터와 소수 1000개를 각각 더함.

위의 동작을 수행하기 위해서는 1) 과 2)의 순서 그리고 1)의 종료 시점을 알 수 없다.

(다른 서버로 데이터의 요청을 보낼 때, 클라이언트는 해당 요청이 언제 완료될지 알 수 없다. )

이처럼 여러 작업들 중 일부 작업들의 시작 종료 시점을 알 수 없는 작업들을 비동기 작업이라고 한다.

이벤트 루프

Js에서는 이벤트 루프를 통해 이러한 비동기 작업을 처리한다.

1. Call stack에서 비동기 callback함수가 호출되면 (api에 요청을 보내는 함수 + 더하는 함수)
2.  해당 비동기 callback 함수를 background(Web API)로 이동한다. 
3. 여기서 background는 call stack이 실행되는 스레드와는 독립적으로 동작한다. 
(응답이 올 때 까지 기다리는 동작 수행)
4. 비동기 작업이 마무리되면 내부함수(소수 1000개와 응답을 더하는 동작)를 task queue 전달한다.
5. Task queue에 전달된 내부함수는 call stack이 빌 때 까지 기다린다.
6. 독립적으로 돌아가는 call stack의 모든 함수가 실행되고 나면 (anonymous까지 종료)
7. 그 때 task queue(callback queue)에 있던 내부함수를 call stack으로 올려서 해당 내부함수를 수행한다.

위의 방법을 사용하면 Js는 서버의 api를 사용할 때 응답을 기다리는 작업을 back ground에서 기다리며 이와는 독립적으로 call stack의 동작들을 수행하게 된다.

이처럼 비동기적인 동작을 백그라운드에서 실행하기 위해서는 비동기 call back함수를 사용한다.

callback 함수란?

  1. 다른 함수의 인자로써 이용되는 함수.
  2. 어떤 이벤트에 의해 호출되어지는 함수.
    CallBack 함수란 이름 그대로 나중에 호출되는 함수를 말한다.
    콜백함수라고 해서 그 자체로 특별한 선언이나 문법적 특징을 가지고 있지는 않다.
    콜백함수도 일반적인 자바스크립트 함수일 뿐이다.
    콜백 함수는 코드를 통해 명시적으로 호출하는 함수가 아니라, 개발자는 단지 함수를 동록하기만 하고, 어떤 이벤트가 발생했거나 특정 시점에 도달했을 때 시스템에서 호출하는 함수를 말한다.

javascript는 비동기 call back함수와 이벤트 루프를 통해 비동기 동작을 효율적으로 구현한다.

하지만 이러한 call back함수는 가독성이 떨어지며 디버깅을 어렵게 한다는 단점이 존재한다.

프로미스란?

이를 해결하기 위해 promise라는 기능이 등장하였다. 그 내부 동작은 기본적으로 call back과 동일하다.

하지만 promise 자체도 디버깅에 어려움을 준다. 이를 개선하여 async/await이 등장하였다.

Ajax

• 자바스크립트를 이용해 서버와 브라우저가 비동기 방식으로 데이터를 교환할 수 있는 통신 기능
Ajax는 웹 페이지 전체를 다시 로딩하지 않고도, 웹 페이지의 일부분만을 갱신할 수 있습니다.
즉 Ajax를 이용하면 백그라운드 영역에서 서버와 통신하여, 그 결과를 웹 페이지의 일부분에만 표시할 수 있다.
Fetch API와 Axio는 promise를 통해 구현되어 있다.

Reference

0개의 댓글