개발자 9Diin의 개발일기

자바스크립트 동기 비동기 방식의 차이점 본문

2021-2023

자바스크립트 동기 비동기 방식의 차이점

9Diin 2022. 8. 8. 08:00
반응형

국비지원 웹 퍼블리셔 과정을 수료한 나는 제법 긴 시간을 학원에서 보냈지만, HTML과 CSS의 기본적인 기능을 활용할 수 있는 수준이었다. 그래봤자 이제 고작 한 달 남짓 개발자의 맛만 본 나로선 한 달 전이나 지금이나 별반 다를게 없다고 생각한다.

내가 너무나도 운이 좋게 취업에 성공했지만, 내 프로그래밍 실력은 시장에서 전혀 쓸모가 없는 수준. 그래도 감사하게도 회사는 나에게 공부할 시간과 기회를 주셨다.

오늘의 주제는 JavaScript의 동기 처리 방식과 비동기 처리 방식을 알아보는 시간을 가져보고자 했는데 서론이 긴 이유는 이 말을 꼭 하고 싶어서랄까?

 

✅ JavaScript 를 몰라도 프로그래밍을 할 순 있지만, JavaScript를 모르면 React, Vue, Angular 같은 프런트엔드 도구들을 활용할 수 없다.

최근 나는 Vue.js를 활용하여 오픈 소스 api를 통해 간단한 미니 웹 애플리케이션을 만들고 있다. 그러나 어찌어찌 완성은 했으나, 뒤따른 'Error' 와 '버그' 들이 너무 많았다. 아직까지 그 원인이 정확히 무엇인지 알지 못하나, 그 에러를 해결하려 노력하는 과정에서 JavaScript의 동기처리 방식과 비동기처리 방식을 공부하게 되었다.

📌 JavaScript 동기처리 방식

JavaScript에서 말하는 동기처리 방식은 무엇일까? 쉽게 얘기하면 코드를 작성한 순서대로 작동하는 것을 동기방식, Synchronous Processing 라고 한다. 아래 코드와 같이 a 라는 함수가 실행된 후에 b 라는 함수가 실행되는 것, 순서대로 로직이 작동되는 방식을 동기처리 방식이라 한다.

그렇기 때문에 JavaScript에서 동기처리 방식이라는 게 어쩌면 당연시 되는 부분이기 때문에 따로 용어를 설정해서 배우지 않는 부분도 아마 JavaScript라는 언어 자체가 위에서 아래로 단계 단계 실행되기 때문이다.

function a(callback) {
  setTimeout(() => {
    console.log("A");
    callback();
  }, 1000);
}

function b() {
  console.log("B");
};

a(function () {
  b(); // callback
});

function b(callback) {
  setTimeout(() => {
    console.log("B");
    callback();
  }, 1000);
};

a(function () {
  b(function () {
    console.log("Done!");
  });
});

📌 JavaScript 비동기처리 방식

자, 그러면 이제 본격적으로 api와 같은 데이터를 처리함에 있어, 우리의 입맛대로 활용하려면 어떻게 해야할까? 라는 고민을 할 수 있는데, 이때 활용할 수 있는 개념이 바로 비동기처리 방식 Asynchronous Processing 이라 한다.

Async 와 await 를 살펴보기 전에 우리가 한 가지 짚고 넘어가야 할 부분이 있는데 바로 Promise 개념이다.

Promise 는 아래 코드 주석 내용과 같이 약속의 객체 라고 부를 수 있다. 즉, Promise는 다음 코드 실행에 대한 보장을 의미한다고 생각하면 된다. 이 객체 안에서는 비동기 작업이 맞이할 미래의 완료 or 실패와 그 결과 값을 나타낸다.

설명이 다소 어려울 수 있으니 아래 코드를 보자.

function a() {
  // Promise: 약속의 객체 => 다음 실행에 대한 약속의 보장
  // Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타낸다.
  return new Promise(function (resolve) {
    setTimeout(function () {
      console.log("A");
      resolve("SON7AE 1"); // 실행 위치를 보장
    }, 1000);
  });
}

function b() {
  console.log("B");
}

async function test() {
  const res = await a();
  console.log("res : ", res);
  b();
}

test();

a 라는 함수 안에는 new 라는 키워드에 Promise 라는 생성자 함수를 설정했다. 그리고 그 안에 콘솔에서 확인을 보다 명확하기 위해 setTimeout 함수를 임의적으로 사용했다.

코드를 위에서 아래로 살펴보면 test 함수가 실행되면 async function test가 함수가 작동하고, 비동기처리 방식에 의해 a 함수가 실행된다. a 함수안에서는 콘솔 안에 'A'가 찍힌 후 resolve 라는 실행위치를 보장하는 메서드 즉, 이 안에 임의의 코딩을 함으로써 실제 a 라는 함수가 실행됐는 지 안됐는 지 증명해주는 역할이라고 이해하면 편할 것 같다. 그 후로 b 라는 함수가 실행된다.

function a() {
  // Promise: 약속의 객체 => 다음 실행에 대한 약속의 보장
  // Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타낸다.
  return new Promise(function (resolve) {
    setTimeout(function () {
      console.log("A");
      resolve("SON7AE 1"); // 실행 위치를 보장
    }, 1000);
  });
}

function b() {
  // Promise: 약속의 객체
  return new Promise(function (resolve) {
    setTimeout(function () {
      console.log("B");
      resolve("SON7AE 2"); // 실행 위치를 보장
    }, 1000);
  });
}

function c() {
  // Promise: 약속의 객체
  return new Promise(function (resolve) {
    setTimeout(function () {
      console.log("C");
      resolve("SON7AE 3"); // 실행 위치를 보장
    }, 1000);
  });
}

function d() {
  // Promise: 약속의 객체
  return new Promise(function (resolve) {
    setTimeout(function () {
      console.log("D");
      resolve("SON7AE 4"); // 실행 위치를 보장
    }, 1000);
  });
}

async function test() {
  const h1 = await a();
  const h2 = await b();
  const h3 = await c();
  const h4 = await d();
  console.log("Done!");
  console.log(h1, h2, h3, h4);
}

test();

따라서 JavaScript 에서의 비동기처리 방식은 await 라는 뜻처럼 어떤 조건의 함수가 비로소 실행되어야지만, 그 이후에 작성된 코드 즉, 프로그래밍이 실행됨을 의미한다고 볼 수 있다. 물론, Async & await 를 짚고 넘어가기 전에

.then() .catch() .finally() 등 ES 2015 버전에서 사용되었던 것들을 활용해서도 비동기처리 방식을 표현할 수 있다. 필자는 실제 Vue.js 미니 프로젝트를 만들 때 위와 같은 메서드들을 활용해서 만들었고, 이 개념은 다음 포스팅에서 알아보도록하자.

반응형