Javascript

동기와 비동기, 이벤트 기반, 프로미스 promise, async, await

selonjulie 2022. 6. 14. 15:32

노드

  • 비동기(Asynchronous) 이벤트-기반(event-driven) JavaScript 런타임 환경

 

비동기

  • 프로그램의 다른 부분(기능 또는 함수)들이 서로 방해(blocking)하지 않고  '동시에' 일어날 수 있음 (언제 실행될지 예측 불가능)
  • 프로그램이 비동기로 돌고있다는 건? 프로세스/스레드가 여럿이 돌고 있다는 것 (멀티태스킹) 
    • ref) 동기 : 코드가 작성된 순서 그래도 '순서대로' 실행됨. 자바스크립트는 '동기'적임. 호이스팅이 된 후부터 하나하나씩 실행됨
      • 호이스팅Hoisting: var 변수와 함수 선언들이 자동으로 제일 위로 올라가는 것
  • 즉, 이전 작업의 마무리 여부에 상관없이 그 다음 일을 처리하는 작업 방식입니다.
  • 비동기를 동기적으로 처리하기 위해 Promise가 사용된다

 

이벤트 기반

  • 이벤트: 프론트엔드(클라이언트)에서 받는 요청 (클릭, 네트워크 요청) 
  • 이벤트 기반: 이벤트가 발생할때 미리 지정해둔 작업을 수행하는 방식
    • 특정 이벤트가 발생할 때 무엇을 할지 미리 지정해두어야함. 이벤트 리스너Event listener 에 콜백Callback함수를 등록한다.
    • 콜백함수는 바로 실행되는 것이 아니라, 함수 안에 하나의 parameter인자로 지정한 함수를 전달해 줌
      • 동기적 콜백 Synchorous callback
      • 비동기적 콜백 Asynchorous callback
    • 콜백지옥을 피하기 위해 Javascript는 ES6부터 promise*를 도입
  • 노드가 비동기적으로 이벤트를 처리한다는 것은, 앞선 클라이언트의 요청이 끝나기 전에, 다음 클라이언트의 요청을 받는다는 의미입니다. 
    • 싱글 스레드 Single-Thread: 한 시점에 여러 요청 수행 (점원이 한 명이고 혼자 많은 일을 수행) 
      • 프로세스: 운영체제에서 할당하는 작업의 단위
      • 스레드: 프로세스 내에서 실행되는 흐름의 단위

 

JavaScript 런타임 환경

  • JavaScript 로 짜여진 소스코드를 CPU가 이해할 수 있는 기계어(ex. 0과 1로 이루어진 bytecode)로 변환시키고 또한 프로그램의 메모리를 관리하는 시스템
  • Chrome V8 엔진: 이 엔진이 브라우저 없이 작동할 수 있도록 만든 환경이 바로 노드
    • 즉, 싱글 스레드 기반의 동작 원리를 이해하고 JavaScript 로 코드를 작성하면 뒷단의 일들(Heavy Load)을 Chrome V8 엔진이 알아서 처리 해 줍니다. 

 

*Promise

  • (콜백을 사용하지 않고) 비동기를 간단하게 처리할 수 있는 자바스크립트의 내장 객체 Object
  • 프로미스를 사용하면 promise 객체를 return함 
    • 상태 State
      • pending
      • ->성공 fullfilled -> 결과값
      • ->실패 rejected-> 에러
    • Producer vs Consumer
      • Producer: 원하는 기능을 수행해서 해당하는 기능을 만들어냄
        • promise는 class이기 때문에 new를 통해서 object를 생성할 수 있음
        • *새로운 콜백함수가 만들어 질때는 우리가 만들어논 executor(resolve, reject인자를 받음)가 즉시 실행됨
      • Consumer: 원하는 데이터를 소비
        • then 성공적인 케이스
        • catch 에러 출력
        • finally 성공,실패 상관없이 무조건 실행
  • 비동기 작업을 하는 함수가 프로미스의 객체를 반환함. 그 생성자에 인자로 들어가는 함수에
    • 첫번째 인자: 수행할 비동기 작업
    • 두번째 인자: 결과물을 콜백함수에 전달 하는 함수

  • 프로미스 반환 함수: promise를 사용한 함수는 그 결과물에 then으로 그 다음 작업을 알려주기 위한 콜백함수를 넣어줄 수 있음 (체이닝 방식)
  • ES8 Async, Await*이 추가됨으로서 프로미스를 직관적이게 실행할 수 있게됨
    • 함수 앞에 Async를 붙이면 비동기 작업을 '마치 동기작업 처럼' 작성할 수 있음
    • await를 추가 
    • 비동기 작업이지만 동기 작업'처럼' 쉽고 직관적이게 코드를 작성할 수 있음 

 

Async, Await

  • 깔끔하게 프로미스를 사용할 수 있는 방법 (syntactic sugar)
    • 프로미스 객체를 return함
  • then을 체이닝하면 코드가 난잡해 질 수 있는데, async, await를 사용해서 직관적으로 사용할 수 있음
    • async: 함수
    • await: 키워드, promise 앞에서 사용
  • promise.all, promise.race API 활용 가능

 

- PrismaPromise는 비동기

- queryRaw는 비동기로 쓰이기 때문에 await를 쓸 수 있다

 

참고

[병맛코딩만화] 비동기 프로그래밍이 뭔가요?

자바스크립트 11. 비동기 처리의 시작 콜백 이해하기, 콜백 지옥 체험 😱 JavaScript Callback | 프론트엔드 개발자 입문편 (JavaScript ES6)