비동기 프로그래밍 ( Asynchronous ) ?

JavaScript 는 단일 스레드에서 동작합니다. => 한번에 한가지 일만 할 수 있습니다. ‘그럼 안 좋은거 아니야?’라고 생각할 수 있지만 싱글 스레드는 멀티 스레드가 겪어야 하는 골치 아픈 문제들을 신경 쓰지 않아도 된다는 장점이 있다.

싱글스레드만으로 멀티스레드 부럽지 않은 부드러운 소프트웨어를 만들기 위해서는 대가를 치뤄야 한다. 그 대가가 바로 비동기적(asynchronous) 프로그래밍이다.

- 하나의 요청 처리가 완료되기 전에 제어권을 다음 요청으로 넘겨 Blocking 되지 않으며 다음 요청을 처리 하는 방식. (ex. nodejs)

출처: https://jinn-blog.tistory.com/87

방식

콜백 방식

  • 자바 스크립트에서 함수는 일급 객체이므로 파라미터로 넘길 수 있음.
    • 일급 객체란?
      • 변수나 데이터에 할당 가능.
      • 객체의 인자로 넘길수 있음.
      • 리턴값으로 사용 가능.
  • 실행 결과를 보면 비동기로 수행되는것을 알수 있음.
  • 위의 전달된 콜백 함수는 디렉토리를 모두 읽은 후 호출됨으로써 비동기 프로그래밍이 가능해짐.
let fs = require('fs');
 
console.log('start');
 
fs.readdir('.', (err, filenames) => {
  if (err) {
    console.error(err);
    return;
  }
  
  for (let i = 0; i < filenames.length; i++) {
    console.log(filenames[i]);
  }
});

console.log('end');
 
 
// 실행 결과: start -> end -> filenames

Promise 방식

  • 복잡한 처리에서는 위의 콜백 방식을 사용할 경우 콜백 헬 발생
  • 비동기 작업을 콜백에 비해 쉽게 컨트롤 가능, 비교적 가독성이 좋음.
  • 오류 처리를 가시적으로 대응할 수 있음.
const fs = require('fs');

function readDirPromise() {
  return new Promise((resolve, reject) => {
    fs.readdir('.', function (err, filenames) {
      err ? reject(err) : resolve(filenames);
    });
  });
}

readDirPromise()
  .then(function (filenames) {
    console.log('filenames - ', filenames);
  })
  .catch(function (error) {
    console.log('error - ', error);
  });

Generator 방식

const fetch = require('node-fetch');

// 외부 api를 사용한다.
function getUser(generatorObject, username) {
  fetch(`https://api.github.com/users/${username}`)
    .then(res => res.json())
    .then(user => {
      // user 이름을 줄테니까 다음을 실행시켜!
      generatorObject.next(user.name)
    });
}

let main;

// 비동기 함수가 포함되어있는 메인함수
function* mainFunction() {
  let user;

  // getUser를 실행하고 멈춰있어!
  user = yield getUser(main, 'jessie');
  console.log('1user - ', user);
  user = yield getUser(main, 'kevin');
  console.log('2user - ', user);
  user = yield getUser(main, 'albert');
  console.log('3user - ', user);
}

// iterator 함수 반환
main = mainFunction();
// main 함수 실행
main.next();

async/await 방식 ( 필자가 가장 많이 쓰는 방식 )

  • async, await 는 ES8(ECMAScript2017)의 공식 스펙(링크)
  • promise, generator보다 더욱 절차적(동기적)인 프로그래밍 방식으로 개발가능
(async () => {
    try {
        const filenames = await fs.readdir('.');
        for (let i = 0; i < filenames.length; i++) {
            console.log(filenames[i]);
        }
    } catch (e) { console.error(e); }
})();

이벤트 루프

https://namjackson.tistory.com/30

 

[NodeJS ]1. Nodejs 동작원리 및 이벤트 루프, 논블로킹I/O (Event Loop , Non-Blocking)

NodeJS란 ? 비동기 이벤트 기반 주도 , JavaScript 런타임으로써, Nodejs는 확장성 있는 네트워크 애플리케을 만들수 있는 언어. Chrome V8엔진 기반의 이벤트 기반( Event-driven ) , 논-블로킹 I/O ( Non-Bloc..

namjackson.tistory.com

jinn-blog.tistory.com/87

 

비동기 프로그래밍

동기(synchronous) 및 비동기(asynchronous) 동기 방식 - 하나의 요청이 처리되는 동안 다른 요청이 처리되지 못하며 요청이 완료되어야만 다음 처리가 가능한 방식. (ex. java) 비동기 방식 - 하나의 요청

jinn-blog.tistory.com

 

+ Recent posts