개요

  • 이번 프로젝트 (handpose, face, pose detection) 을 진행하면서 비동기로 작업을 처리하는 경우가 매우 많았음.
  • 특히 모델 로딩, 좌표 예측 에 해당하는 부분이 시간이 오래 걸리는 작업이었기 때문임
  • 그러나 ①비동기 개념에 대한 이론을 매우 오래 전에 배우기도 했고, ②회사의 기존 코드는 Promise 를 활용하여 작성되었는데 나는  async, await  코드 작성법만 알고 있는 상황이어서 주먹구구식으로 따라감. 그래서  Promise 에 대해서도 공부해보고 싶었음 
  • 따라서 비동기 처리에 관한 내용들을 시리즈로 정리할 것임. 이번 글의 모든 코드와 글은 근본적으로  https://ko.javascript.info/callbacks 을 출처로 함 

 


 

1. 비동기 (Asynchronous)

의미
  • 작업이 완료될 때까지 기다리지 않고, 다른 작업을 수행
    = 백그라운드에서 작업을 수행하고, 그 작업이 완료되면 특정 콜백 함수, 프로미스 등을 통해 결과를 처리
  • JS에서 비동기 스케줄링 대표 예시 : setTimeout() , AJAX 요청, 파일 읽기

 

필요성
  • 일반적
    • 대규모 응용 프로그램에서 보다 효율적인 성능 제공
    • 여러 작업을 동시에 수행 가능. 따라서 다수 클라이언트 요청에도 (ex. 네트워크 통신 및 파일 I/O, 이벤트 처리 등) 웹 어플리케이션이 보다 빠르게 동작하고, UX 향상 가능
  • 나의 프로젝트 (구체적으로)
    • createDetector() 함수 : 파일 시스템에 저장된 모델을 불러오는데(I/O 작업) 시간 오래 걸림
    • estimateHands() 함수 : 모델로 예측하는 인공지능 업무 수행하는 데에 시간 오래 걸림
  • 기본적인 비동기 처리 방법 : 콜백

 


 

2. 콜백

의미
  • 어떤 일이 발생했을 때 시스템에서 호출되는 함수 = 나중에 호출할 함수. 따라서 개념 상 주로 비동기 상황 (ex. 이벤트 발생, 비동기 작업 완료) 에서 사용됨
  • 비동기 함수는 콜백을 인수로 반드시 제공해야 함.
    (콜백 : 함수 내 동작이 모두 처리된 후 실행되어야 하는 함수가 들어간 콜백임)
  • 콜백 함수의 의미 : 콜백의 의미와 매우 유사
const fs = require('fs');
// 콜백 함수 : readFile() 함수의 마지막 인자로 전달된 함수
fs.readFile('example.txt', 'utf8', (err, data) => { 
    if (err) {
        console.error('Error reading file:', err);
        return;
    }
    console.log('File contents:', data);
});
console.log('Reading file...');

 

콜백 지옥 (= 멸망의 피라미드)
  • 발생 이유 : 중첩된 콜백 코드가 많아지는 경우 발생
  • 예시 코드
loadScript('1.js', function(error, script) {

  if (error) {
    handleError(error);
  } else {
    // ...
    loadScript('2.js', function(error, script) {
      if (error) {
        handleError(error);
      } else {
        // ...
        loadScript('3.js', function(error, script) {
          if (error) {
            handleError(error);
          } else {
            // 모든 스크립트가 로딩된 후, 실행 흐름이 이어집니다. (*)
          }
        });

      }
    })
  }
});

 

해결법
  • Promise 문 사용
    • 특히 콜백을 단 한 번만 호출하는 함수인 경우, 프로미스화하여 사용하면 좋음
    • 콜백을 단 한 번만 호출할 때만 프로미스화 해야 하는 이유 : 콜백은 2개 이상의 결과를 가질 수 있지만, 프로미스는 1개의 결과만 가지기 때문
    • 프로미스화 : 콜백을 받는 함수를 프로미스를 반환하는 함수로 바꾸는 것 . 프로미스화는 async, await 과 같이 사용하면 좋음
  • async, await 함수 사용 : Promise를 보다 쉽게 사용하는 도구

 


 

요약

  • 비동기 처리는 시간이 오래 걸리는 작업이어도 백그라운드에서 다른 작업을 수행할 수 있도록 함. 따라서 기능 실행의 효율성 측면에서 필수불가결한 작업임.
  • 비동기 처리의 대표적인 방법인 콜백은 콜백 지옥에 빠질 확률이 매우 높기 때문에, Promise 또는 async, await 함수의 활용이 절실

 

+ Recent posts