본문 바로가기
공부/JavaScript

비동기 처리

by 무심한고라니 2020. 12. 27.

자바스크립트는 그 자체로는 동기적인 언어[1]입니다. 하지만 많은 사람들이 자바스크립트를 자바 등과 다르게 비동기적인 언어라고 알고 있습니다. 바로 다음과 같은 때문입니다.

 

setTimeout(() => console.log("Horse A"), 0);
console.log("Horse B");

 

위 코드의 실행 결과는 위에서부터 순서대로 찍히지 않고 Horse B가 먼저 찍힙니다. 이처럼 자바스크립트가 특정 환경에서 실행할 때, 다시 말해 서버와의 네트워크 통신이나 setTimeout 함수와 같은 웹 API[2]를 사용할 경우 비동기적으로 동작합니다. 이 글에서는 자바스크립트가 다양한 환경에서 비동기 처리를 어떤 식으로 해왔는지에 대해 적어보고자 합니다. 공부 목적으로 적은 글이니 틀린 부분이나 피드백이 있다면 댓글로 남겨주시면 감사하겠습니다. 미비된 부분은 공부를 하며 채워나갈 계획입니다. 이 글의 목차는 다음과 같고 참고자료는 하단에 기재하였습니다.

 

1. Callback

2. Promise

3. Async, Await

4.

5. 폴리필 사용하기

 

_____

 

Callback

 

웹 개발자라면 한번쯤 콜백 지옥이라는 말을 들어봤을 것이다. 이는 비동기 처리를 위해 콜백 함수[3]를 사용했을 때 발생하는 문제로, 함수의 매개 변수로 넘겨지는 콜백 함수의 들여쓰기 수준이 깊어지는 것을 말한다. 그렇다면 콜백 함수가 무엇이길래 비동기 처리의 해결 방법이 될 수 있을까? 콜백 함수가 무엇인지 간단한 코드로 살펴보면 아래와 같다(출처: 비동기 처리의 시작 콜백 이해하기, 콜백 지옥 체험).

 

'use strict'; // [4]

// Synchronous callback
function printImmediately(print) {
    print();
}
printImmediately(() => console.log('hello'));

// Asynchronous callback
function printWithDelay(print, timeout) {
    setTimeout(print, timeout);
}
printWithDelay(() => console.log('async callback'), 2000);

 

이처럼 콜백 함수는 다른 함수의 파라미터로 넘겨주는 함수를 말한다. 그리고 위에서 보는 바와 같이 콜백 함수는 즉시 실행될 수도 있고, 나중에 실행될 수도 있다. 아래 비동기 코드를 살펴보자.

 

console.log('Hello');

setTimeout(function() {
    console.log('Bye');
}, 3000);

console.log('Hello Again');

 

우리가 원하는 것은 Hello, Bye, Hello Again인데 순서가 원하는대로 출력되지 않는 것을 확인할 수 있다. 이를 콜백 함수를 이용해 아래와 같이[5] 해결할 수 있다.

 

function hello(callback1, callback2) {
    console.log('Hello');
    callback1(callback2);
};

function bye(callback) {
    setTimeout(function() {
        console.log('Bye');
        callback();
    }, 3000);
};

function helloAgain() {
    console.log('Hello Again');
};

hello(bye, helloAgain);

 

즉 비유하자면 콜백 함수의 동작 방식은 일종의 식당 자리 예약[6]과 같다. 대기자 명단을 쓴 뒤 주변을 돌아다니다가 식당에 자리가 나면 연락을 받게 되는 것과 비슷하다. 추가적으로 콜백 함수를 이용해 비동기 처리를 했을 때, 콜백 지옥의 예는 다음 코드와 같다(출처: 비동기 처리의 시작 콜백 이해하기, 콜백 지옥 체험).

 

 

Promise

 

작성 예정

 

 

Async, Await

 

 

 

 

폴리필 사용하기

 

먼저 브라우저가 Promise를 지원하는지 여부를 부정 연산자를 이용해 다음과 같이 테스트할 수 있다.

 

if (!window.Promise) {
    alert("구식 브라우저를 사용 중이시군요!");
    window.Promise = ... // 모던 자바스크립트에서 지원하는 기능을 직접 구현함
}

 

Promise와 같은 명세에 있는 기능이지만 해당 기능을 지원하지 않는 오래된 브라우저를 사용하고 있다면 위와 같이 직접 함수를 만들어 전역 객체에 추가하는 방식으로 폴리필[10]을 만들 수 있다.

 

 

_____

1. JavaScript is a single-threaded programming language which means only one thing can happen at a time(출처: Understanding Asynchronous JavaScript).

// JavaScript is synchronous.
// Execute the code block by order after hoisting.
// hoisting: var, function declaration
console.log('1');
setTimeout(() => console.log('2'), 1000);
console.log('3');

2. JavaScript는 ECMAScript 사양(ex. map, reduce, forEach etc)을 준수하는 범용 스크립트 언어다. 즉 JavaScript의 표준은 ECMAScript인데, 반면 Web API의 표준(ex. console, setTimeout, fetch etc) 관리는 WHATWG에서 담당한다.

3.

4.

5. 다음과 같이 해결할 수도 있으나 뭔가 찝찝하다.

function hello(callback) {
    console.log('Hello');
    callback;
};

function bye(callback) {
    setTimeout(function() {
        console.log('Bye');
        callback();
    }, 3000);
};

function helloAgain() {
    console.log('Hello Again');
};

hello(bye(helloAgain));

6.

10. 폴리필(polyfill)은 기본적으로 지원하지 않는 이전 브라우저에서 최신 기능을 제공하는 데 필요한 코드다. 즉 개발자가 특정 기능이 지원되지 않는 브라우저를 위해 사용할 수 있는 코드 조각이나 플러그인을 말한다.

 

 

_____

참고자료

 

'공부 > JavaScript' 카테고리의 다른 글

기타  (0) 2021.01.03
var과 let의 차이점  (0) 2021.01.02
느슨한 연결  (0) 2020.12.27
Function  (0) 2020.12.26
Logical Operators  (0) 2020.12.25

댓글