CS/클린코드(cleancode)

13장. 동시성(Concurrency) - 자바스크립트 클린코드

rachel_13 2022. 12. 5. 23:23

동시성(Concurrency)

콜백지옥은 프론트엔드 개발자라면, 한 번쯤은 겪어봤을 것이다.

중첩의 중첩의 중첩을 만들어내는 콜백은 최대한 지양해야 한다.

콜백이 대체 무엇이길래?

  • 다른 함수의 인자(argument)로 넘겨주는 함수이다.
  • 함수와 함수를 연결해준다고 생각하면 이해하기 쉽다.

 

[동기 vs 비동기]

자바스크립트는 단일(single) 스레드 프로그래밍 언어이다.

동기 = 싱글 스레드 = 순차적 실행 모두 동일한 의미이다.

  • 싱글 스레드는 하나의 코드가 실행되어 끝난 시점에 다음 코드 시작 지점이 연결된 형태이다.
  • 단일 스레드는 선행 작업이 완료될 때까지, 다른 일을 수행하지 못하고 기다린다.

-> 블로킹 발생 (콜 스택 멈춤 상태)

  • 한 번에 하나의 콜 스택을 가진다. 
// 동기적으로 3초 마다 배열의 수가 출력된다. (블로킹을 느낄 수 있다.)
[1, 2, 3].forEach((num) => {
 // 콘솔 한번 찍히려면 매번 3초씩 걸린다.
 // 이 함수의 콜백 함수는 동기적으로 호출된다.
callBackFunc(() => console.log(num), 3000);
});

function callBackFunc(callback) {
 let start = Date.now();
 let now = start;
 while( now - start < 3000 ) {
     now = Date.now();
 }
 callback();
}
// 콘솔 출력까지 총 수행 시간 3 * 3 = 9초
// 의도적으로 타이머의 기능이 필요하다면 동기적 콜백 호출이 필요할 수도 있다.

비동기 = 멀티 스레드 = 동시에 실행

  • 여러 코어를 사용하여 여러 작업을 동시에 수행한다.
  • 논 블로킹
  • 일단 쌓아두고, 동시에 처리하기 시작해서 요청이 완료되는 순서대로 처리한다.
  • 웹 브라우저의 Web APIs는 비동기로 처리한다.

    (Web APIs : setTimeout, DOM, AJAX(HTTP))

  • Web API
// 비동기적으로 3초 이후 배열의 수가 출력된다. (논 블로킹을 느낄 수 있다.)
[1, 2, 3].forEach((num) => {
  // 자바스크립트 런타임의 'Web API'인 'setTimeout' 함수를 사용함으로써
   // 3초 이후 콘솔이 모두 출력된다.
   // 이 함수의 콜백 함수는 비동기적으로 호출된다.
   setTimeout(() => console.log(num), 3000);
});
// 콘솔 출력까지 총 수행 시간 = 3초
// 블로킹을 해결하고 속도를 개선하려면 비동기적 콜백 호출을 이용한다.

해결방법 : Promise 객체 사용하기

안좋은 예:

require('request').get('https://apis, (requestErr, response) => {
  if (requestErr) {
    console.error(requestErr);
  } else {
    console.log(response.data);
    });
  }
});

 

좋은 예:

require('request-promise').get('https://apis')
  .then((response) => {
    console.log(response.data);
  })
  .catch((err) => {
    console.error(err);
  });

 

더 좋은 방법 async/await

async function getData() {
  try {
    const response = await require('request-promise').get('https://apis');
    console.log(response.data);
  } catch(err) {
    console.error(err);
  }
}