[JS] 동기 & 비동기

이재훈·2023년 6월 5일
0

javascript

목록 보기
9/13
function working1() {
  console.log("working1");
}

function working2() {
  console.log("working2");
}

function working3() {
  console.log("working3");
}

working1();
working2();
working3();

예를 들어 3개 task가 존재하고 모두 실행해야 한다고 가정해보겠습니다.
이 때 순서는 상관이 없다는 가정입니다.

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

자바스크립트는 코드가 작성된 순서대로 작업을 처리합니다.
이전 작업이 진행 중일 때는 다음 작업을 수행하지 않고 기다립니다.
먼저 작성된 코드를 먼저 다 실행하고 나서 뒤에 작성된 코드를 실행합니다. (동기 방식 처리)

하지만 동기 처리의 단점은 하나의 작업이 오래 걸릴 시, 모든 작업이 오래 걸리는 하나의 작업이 종료되기 전에는 수행할 수 없게 됩니다.

싱글 쓰레드 방식을 이용하면서, 동기 작업의 단점을 극복하기 위해서 자바스크립트는 여러개의 작업을 동시에 실행시켜 버립니다. (일부 비동기 함수들)
즉, 먼저 작성된 코드의 결과를 기다리지 않고 다음 코드를 바로 실행합니다.
(비동기 방식 처리)

이렇게 비동기 처리를 하게되면 잘 작업이 되었는지 확인하는 방법을 추가해 주어야 합니다. 콜백 함수를 사용하여 작업이 잘 완료 되었는지 확인이 가능합니다.

function work1() {
  console.log("work1");
}

work1();
console.log("work finish");

위의 코드는 당연하게 work1 이 출력되고 work finish가 출력됩니다.
동기 방식 처리입니다.

function work1() {
  setTimeout(() => {
    console.log("work1");
  }, 3000);
}

work1();
console.log("work finish");

비동기 처리 함수인 setTimeout을 사용하였습니다. work finish 가 먼저 출력되고 work1이 출력되는 것을 확인할 수 있습니다.

function work1(a, b) {
  setTimeout(() => {
    const result = a + b;
  }, 3000);
}

work1(3, 5);
console.log("work finish");

함수 work1은 매개변수로 받은 두 개의 값을 더하는 함수입니다.

function work1(a, b, callback) {
  setTimeout(() => {
    const result = a + b;
    callback(result);
  }, 3000);
}

work1(3, 5, (result) => {
  console.log(`work1 result = ${result}`);
});
console.log("work finish");

매개변수로 받은 callback 함수를 사용하여 result를 출력을 할 수 있습니다.

콜백 함수를 사용하는 이유는 테스크가 끝난 직후에 실행되기 때문에 콜백함수는 비동기 자바스크립트 코드를 여러 문제와 에러들로 부터 안전을 보장해줍니다.

function work1(a, b, callback) {
  setTimeout(() => {
    const result = a + b;
    callback(result);
  }, 3000);
}

function work2(a, callback) {
  setTimeout(() => {
    const result = a * 2;
    callback(result);
  }, 2000);
}

work1(3, 5, (result) => {
  console.log(`work1 result = ${result}`);
});

work2(10, (result) => {
  console.log(`work2 result = ${result}`);
});
console.log("work finish");

work2도 만들어 보겠습니다.

이렇게 결과가 나오는 것을 확인할 수 있습니다.

function work1(a, b, callback) {
  setTimeout(() => {
    const result = a + b;
    callback(result);
  }, 3000);
}

function work2(a, callback) {
  setTimeout(() => {
    const result = a * 2;
    callback(result);
  }, 2000);
}

function work3(a, callback) {
  setTimeout(() => {
    const result = a * -1;
    callback(result);
  }, 2500);
}

work1(3, 5, (result) => {
  console.log(`work1 result = ${result}`);
});

work2(10, (result) => {
  console.log(`work2 result = ${result}`);
});

work3(2, (result) => {
  console.log(`work3 result = ${result}`);
});

console.log("work finish");

이 코드에서 호출 부분을 바꿔보도록 하겠습니다.

function work1(a, b, callback) {
  setTimeout(() => {
    const result = a + b;
    callback(result);
  }, 3000);
}

function work2(a, callback) {
  setTimeout(() => {
    const result = a * 2;
    callback(result);
  }, 2000);
}

function work3(a, callback) {
  setTimeout(() => {
    const result = a * -1;
    callback(result);
  }, 2500);
}

work1(2, 4, (work1_res) => {
  console.log(`work1 result = ${work1_res}`);
  work2(work1_res, (work2_result) => {
    console.log(`work2 result = ${work2_result}`);
    work3(work2_result, (work3_res) => {
      console.log(`work3 result = ${work3_res}`);
    });
  });
});
console.log("work finish");

결과 출력은 아래와 같습니다.

이렇게 콜백함수에 콜백함수에 콜백함수를 넣어서 비동기 처리의 결과를 또다른 비동기 처리의 값으로 넣을 수 있습니다. 생각보다 흔한 경우입니다.
하지만 가독성이 좋지 않고 콜백 지옥이 펼쳐집니다.

콜백 지옥을 없애기 위해 자바스크립트에서 지원하는 비동기 담당 객체가 있습니다. 바로 "promise" 입니다.

다음 게시글에서 promise를 정리해보도록 하겠습니다.


해당 게시글은 인프런 강의
"한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지(이정환)"
를 정리한 내용입니다. 쉽게 잘 설명해주시니 여러분도 강의를 듣는 것을 추천드립니다.

profile
부족함을 인정하고 노력하자

0개의 댓글