웹을 공부하다보면 axio, promise, callback 등의 여러 기능을 공부하게 된다. 또한 글을 조금만 찾아보면 이러한 기능은 "비동기"라는 동작과 관련되어 있다는 사실을 알 수 있다. 이번 포스트에서는 이 "비동기"가 무엇이고 javascript에서 "비동기"작업을 어떻게 구현하는 지 얕게 알아본다.
작업을 하는 주체와 대상이 2개 이상인 상황에서 비동기와 동기를 구분한다.
작업의 주체와 대상이 2개 이상인 상황에서 Block과 non-Block을 구분한다.
실제로 비동기와 동기를 구분하는 기준과 block vs non-block을 구분하는 기준은 다르다. 따라서 다음의 조합이 가능하다.
기초적인 프로그래밍에서는 대부분 함수의 시작과 종료를 논리적으로 예측할 수 있다.
이처럼 작업들의 시작/종료 시점 및 순서를 결정할 수 있는 작업들을 동기 작업이라고 한다.
예를 들면
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함수를 사용한다.
javascript는 비동기 call back함수와 이벤트 루프를 통해 비동기 동작을 효율적으로 구현한다.
하지만 이러한 call back함수는 가독성이 떨어지며 디버깅을 어렵게 한다는 단점이 존재한다.
이를 해결하기 위해 promise라는 기능이 등장하였다. 그 내부 동작은 기본적으로 call back과 동일하다.
하지만 promise 자체도 디버깅에 어려움을 준다. 이를 개선하여 async/await이 등장하였다.
• 자바스크립트를 이용해 서버와 브라우저가 비동기 방식으로 데이터를 교환할 수 있는 통신 기능
Ajax는 웹 페이지 전체를 다시 로딩하지 않고도, 웹 페이지의 일부분만을 갱신할 수 있습니다.
즉 Ajax를 이용하면 백그라운드 영역에서 서버와 통신하여, 그 결과를 웹 페이지의 일부분에만 표시할 수 있다.
Fetch API와 Axio는 promise를 통해 구현되어 있다.