728x90

용어의 개념은 헷갈리지 않도록 다음과 같이 잡고 가겠다.
주체 : main. 다른 주체를 호출하는 함수
다른 주체 : main에서 호출하는 함수.

Blocking vs Non-Blocking

다른 주체가 작업할때 "제어권"이 해당 주체에게 넘어가는지 넘어가지 않는지로 구분.

  • Blocking
    • 다른 주체가 작업할 때 제어권이 주체에서 다른 주체에게 넘어간다.
    • 다른 주체가 작업이 끝날때까지 주체는 모든 작업을 중단하고 결과가 return 될때까지 기다린다.
  • Non-Blocking
    • 다른 주체의 작업완료 여부에 관련 없이 자신의 작업을 이어간다.
    • synchronous 기반 언어에서 다른 주체는 주체에게 요청 받는 즉시 응답을 보내 주체가 계속 제어권을 가질수 있도록 해준다.

Synchronous vs Asynchrnous

다른 주체에서 결과를 돌려주었을 때 어느 주체가 코드의 순서와 해당 결과에 관심이 있는지 아닌지로 구분.

  • Synchronous
    • 주체가 다른주체의 작업 완료 여부에 신경을 쓰게 되어 작업을 동시에 수행하거거나, 동시에 끝내거나, 끝나는 동시에 시작함을 의미
    • 예를 들어 송금 서비스가 있다. A가 B에게 송금 메시지 전송, B가 A에게 수금 성공 메시지 전송, 이후 A와 B는 각각 차액 증액 시행.
      • 요청과 응답이 발생한 후 이 결과를 바탕으로 동시에 같은 작업을 동시에 함.
    • 응답 값이 곧 작업 결과와 일치한다.
  • Asynchronous
    • 주체가 다른주체의 작업 완료 여부에 신경을 쓰지 않아 시작, 종료가 일치하지 않으며, 끝나는 동시에 시작을 하지 않음을 의미
    • 응답 값이 작업 결과가 함께 전송되지 않고 값도 다를 수 있다.
    • js에서 비동기 처리를 할 때, axios의 return 값은 바로 promise를 반환한다.

Blocking - Synchronus

  • 주체는 다른 주체를 호출 하면서 동작하지 않고 기다린다. 이후 다른 주체가 작업 결과를 반환하면 주체는 비로소 그 결과를 바탕으로 작업을 개시한다.
  • Blocking - Synchronous의 예시로는 Java의 scanner 입력요청이 있다. 입력요청을 하는 순간 프로그램은 스탑하며(blocking) 입력결과가 반환된 순간 이 결과를 바탕으로(sync) 이후의 작업이 이어진다.
  • const fs = require('fs');
    const data = fs.readFileSync('/file.md'); // 파일을 읽을 때까지 여기서 블로킹 됩니다.

NonBlocking - Synchronous

  • 주체는 다른주체에 요청을 보낸 후, 다른 주체의 작업 결과를 기다리지 않고 본인의 작업을 계속한다. 이 때 주체는 다른 주체에게 중간중간 해당 작업이 끝났는지 물어본다. 이 결과 다른 주체가 작업 결과를 반납하면 주체는 그 결과를 바탕으로 작업을 개시한다.
  • NonBlocking - Synchronous의 예시로는 정보의 로드율(다운로드. 업로드)이 얼마만큼인지 보여줄 때이다. chrome에서 파일을 받을동안 사용자는 인터넷 서핑을 계속 이어갈 수 있다.(non-blocking) 그리고 다운로드가 진척되는 중간중간 진행정도(%)를 사용자에게 실시간 UI 보여준다.(synchronous)

Blocking - Asynchronous

  • 주체는 다른주체에게 요청을 보낸 후 동작하지 않고 멈춘다. 하지만 주체는 다른 주체의 작업 결과값에 관심이 없다.
  • asynchronous이기 때문에 다른 주체는 바로 결과를 반환하고 이후 작업을 시작한다. 하지만 주체는 작업결과를 기다린다.
    • async 함수가 응답과 작업결과가 다른 함수인데 blocking으로 작업결과가 나오기까지 기다린다라... blocking/sync와 별반 다를바 없어보인다. 이런 상황은 주로 개발자 실수로 만들어진 경우가 대다수다.

NonBlocking - Asynchronous

  • 주체는 다른 주체에게 요청을 보낸후, 다른 주체의 작업 결과를 기다리지 않고 본인의 작업을 계속한다. 다른 주체는 요청받은 작업을 하다가 작업이 끝나면 주체의 callback함수를 실행한다.
  • js의 비동기 처리가 이에 해당한다.(정밀하게는 동기적으로 작동하지만) 주체가 다른 주체를 호출하고 바로 주체 본연의 일을 한다.(비동기 함수는 바로 promise를 반환하기때문에 동기적으로 작동해도 이것이 가능) 이후 다른 주체가 결과를 도출하면 이 결과를 바탕으로 주체에 있던 callback함수를 실행한다. 각자 본인의 일을 하고 잇는 것이다.
  • const fs = require('fs');
    fs.readFile('/file.md', (err, data) => {
      if (err) throw err;
    });

Javascript 에서 의미하는 async/ await 는?

비동기 처리란?

특정 코드의 연산이 끝날 때 까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성이다. 동기 처리를 사용할 시 비동기 작업 결과값을 마냥 기다릴 수 없기 때문에 기본적으로 비동기 처리를 사용한다.

비동기 처리 방식에는 작업결과를 이용할 수 없다는 문제점이 있다. 이 문제점을 JS에서는 비동기함수(ex. axios)가 callback함수를 넘겨받아 해결하도록 함으로써 해결한다.(callback, promise, await)

async

async function 의 의미는 이 함수가 promise vlaue를 반환할 것이라는 의미이다. 즉, 직역적으로도 비동기 함수라는 뜻이다.
async 함수는 보통 내부에서 await를 사용중일 때 선언하는데 await또한 비동기 함수의 promise.value를 반환받을 때까지 기다리는 기능을 하므로 await를 선언한 함수도 어쩔 수 없이 비동기 함수가 되게된다.

await

await는 얼핏보면 async 함수내에서 await를 호출한 시점부터 이후의 코드의 실행을 멈추는 Blocking 기능을 한다고 볼 수 있다.

하지만 정확히 따져보면 await는 Blocking 기능을 수행하지 않고 있다.
그 이유는 실제 Blocking이 일어나고 있었다면 await하는 동안 해당 프로그램은 이벤트 처리를 할 수 없어야한다. 하지만 await 중에도 이벤트 발생시 이벤트 처리는 이벤트 처리대로 실행할 수 있다.

결론: async 함수는 내부적으로 blocking/sync 로 보일 수 있다. 하지만 현실은 promise.then 기반의 non-blocking/ async 구조이다. 그리고 async함수는 그 자체적으로 promise를 반환하는 async 함수이다.

'기타' 카테고리의 다른 글

MVC 란?  (0) 2021.05.19
library vs framework  (0) 2021.03.07
CI(continuous Integration)/CD(Continuous Delivery/Continous Deployment)  (0) 2021.02.11

+ Recent posts