Web/JavaScript

JavaScript 응용 #3 동기 & 비동기

ansui 2023. 9. 16. 21:25

#7 동기 & 비동기

< 자바스크립트의 싱글 스레드 작업 수행 방식 >

: 자바스크립트는 코드가 작성된 순서대로 작업을 처리함

: 이전 작업이 진행 중 일때는 다음 작업을 수행하지 않고 기다림 (동시 수행 x)

: 먼저 작성된 코드를 먼저 다 실행하고 나서 뒤에 작성된 코드를 실행한다.

→ 동기 방식의 처리 (=블로킹 방식)

 

< 동기적 처리의 단점 >

: 하나의 작업이 너무 오래 걸리게 될 시, 

모든 작업이 오래 걸리는 하나의 작업이 종료되기 전까지 기다려야 하므로 전반적인 흐름이 느려진다.

 

< 멀티 쓰레드 >

: 코드를 실행한는 일꾼 Thread를 여러개 사용하는 방식

: 작업 분할 가능

 

< 비동기 작업 >

*자바스크립트는 싱글 쓰레드로 동작

싱글 쓰레드 방식을 이용하면서, 동기적 작업의 단점을 극복하기 위해 여러개의 작업을 동시에 실행시킨다.

→ 먼저 작성된 코드의 결과를 기다리지 않고 다음 코드를 바로 실행

→ 비동기 작업 (=논 블로킹 방식)

 

< 작업의 결과 확인 >

: 콜백함수 이용

function taskA((resultA) => {
  console.log(`A 끝났습니다. 작업 결과 : ${resultA}`);
} //A콜백

 

< 동기적 방식 예시 >

function taskA() {
  console.log("A 끝났습니다.");
}

taskA();

console.log("코드 끝")

//A 끝났습니다. 코드 끝

 

< 비동기적 방식 예시 >

function taskA() {
  setTimeout(() => {
    console.log("A TASK END");
  }, 2000);
} //2초 뒤에 콜백함수 실행

taskA();
console.log("코드 끝")


function taskB(a, b, cb) {
  setTimeout(() => {
    const res = a + b;
    cb(res);
  }, 3000);
}

taskB(3, 4, (res) => {
  console.log("B TASK RESULT : ", res);
});
console.log("코드 끝")


function taskC(a, cb) {
  setTimeout(() => {
  const res = a * 2;
  cb(res);
  }, 1000);
}

taskC(7, (res) => {
  console.log("C TASK RESULT : ", res);
});
console.log("코드 끝")

: C는 1초, A는 2초, B는 3초 기다리기 때문

 

< JS 엔진 >

- Heap

: 변수나 상수들에 사용되는 메모리

- Call Stack

: 작성한 코드의 실행에 따라서 호출 스택을 쌓는다.

 

 

< 동기방식 JS Engine >

function one() {
  return 1;
}

function two() {
  return one() + 1;
}

function three() {
  return two() + 1;
}

console.log(three());

[ Call Stack ]

- Main Context in

: 실행이 시작되면 가장 최상위 문맥인 Main Context가 Call Stack에 가장 먼저 들어온다.

: 들어오면 프로그램 실행 / 나가면 프로그램 종료

- three() in

- two() in

- one() in

- one() out

- two() out

- three() out

- Main Context out

: 프로그램 종료

> 3

 

< 비동기 방식 JS Engine, Web APIs, Callback Queue >

function asyncAdd(a, b, cb) {
  setTimeout(() = > {
    const res = a + b;
    cb(res);
  }, 3000);
}

asyncAdd(1, 3, (res) => {
  console.log("결과 : ", res);
});

 

Call Stack Web APIs
- Main Context in
- asyncAdd() in
- setTimeout() in
- cb() in
- asyncAdd() out
- cb() in

- Main Context out
- setTimeout() in
- cb() in
Callback Queue
- cb() in

 

< 예시 >

function taskA(a, b, cb) {
  setTimeout(() => {
    const res = a + b;
    cb(res);
  }, 2000);
}

function taskB(a, cb) {
  setTimeout(() => {
    const res = a * 2;
    cb(res);
  }, 3000);
}

function taskC(a, cb) {
  setTimeout(() => {
  const res = a * -1;
  cb(res);
  }, 1000);
}

taskA (4, 5, (a_res) => {
  console.log("A RESULT: ", a_res);
  taskB (a_res, (b_res) => {
    console.log("B RESULT: ", b_res);
    taskC(b_res, (c_res) => {
      console.log("C RESULT : ", c_res);
    });
  });
});

→ 콜백 지옥 발생!

→ Promise로 해결


이정환님의 인프런 강의 "한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지"를 참고하여 작성하였습니다.