본문 바로가기

Posts/JavaScript

비동기, 프로미스, 콜백함수 정리

반응형

동기/비동기 처리란?

동기 처리 모델은 직렬적으로 작업을 수행하는 것을 말합니다. 보통 우리는 코드를 작성할 때 위에서 아래로 순차 실행을 기대하는데 이를 동기 처리 모델이라 합니다. 순차적으로 실행할 때 먼저 시작한 작업이 실행중이라면 다음 작업은 대기하게 되는 특성을 가지고 있습니다. 동기 처리는 서버에 요청을 보내 데이터를 화면에 보여주는 과정에서 서버에서 응답을 돌려줄때까지 대기하는 것을 예로 들 수 있습니다.

function demo1() {
    console.log('function 1');
    demo2();
}

function demo2() {
    console.log('function 2');
    demo3();
}

function demo3() {
    console.log('function 3');
}

demo1();
//function 1
//function 2
//function 3

비동기 처리 모델은 병렬적 작업을 수행하는 것을 말하며 작업이 종료되지 않은 상태여도 대기하지 않고 다음 작업을 실행합니다. 예로 DOM 이벤트 헨들러, Timer 함수, ajax등이 있습니다. 아래와 같은 코드가 있을때 우리는 순차적으로 실행될 것으로 기대하지만 비동기 처리 함수 특징상 setTimeout 콜백함수는 바로 실행되지 않고 지정 대기시간을 기다리다 이벤트가 발생하면 작업 큐로 이동 후 call stack이 비어져 있을때 call stack으로 이동되어 실행됩니다.

function demo1() {
  console.log('demo1');
  demo2();
}

function demo2() {
  setTimeout(function() {
    console.log('demo2');
  }, 0);

    demo3();
}

function demo3() {
  console.log('demo3');
}

demo1();
//demo1
//demo3
//demo2

async-vs-sync-concurrency-in-javascript-large

비동기와 동기 모델의 차이

콜백 함수 비동기 처리 방식

콜백 함수란 다른 코드의 인수로 넘겨주는 실행 가능한 코드를 말합니다. 콜백 함수는 실행하는 동안에 넘겨받은 콜백을 필요에 따라 호출하고 다른 작업을 실행하는 경우도 있습니다. 쉽게 말해 다른 함수의 인자로 사용되거나 이벤트에 의해 호출되는 함수라고 볼 수 있습니다.

이러한 콜백 함수로 특정 함수를 사용하여 특정 작업 종료 후 원하는 동작을 실행함으로써 비동기 처리 방식을 해결할 수 있습니다. 하지만 콜백 함수를 많이 사용하다보면 코드의 가독성이나 콜백에 반복으로 인해 재사용도 어렵게 됩니다. 이를 해결하기 위해 나온 방법이 Promise, Async입니다.

doSomething(function(result) {
  doSomethingElse(result, function(newResult) {
    doThirdThing(newResult, function(finalResult) {
      console.log('final result: ' + finalResult);
    }, failureCallback);
  }, failureCallback);
}, failureCallback);

콜백지옥 >_

Promise

ES6 자바스크립트 비동기 처리에 사용되는 객체를 말합니다. 비동기 작업의 완료, 또는 실패를 나타내며 함수에 콜백을 전달하는 대신 첨부하는 방식의 객체로 사용합니다.

프로미스는 Promise 생성자 함수를 인스턴스화하여 사용하며 수행할 콜백 함수를 인자로 받는데 이 콜백 함수는 resolve와 reject함수를 인자로 전달받는 특징을 가지고 있습니다.

const promise1 = new Promise(function(resolve, reject) {
  resolve('Success!');
});

promise1.then(function(value) {
  console.log(value);
  // expected output: "Success!"
});

Promise의 상태값은 다음과 같습니다.

상태 의미 구현
pending 비동기 처리가 아직 수행되지 않은 상태 resolve 또는 reject 함수가 아직 호출되지 않은 상태
fulfilled 비동기 처리가 수행된 상태 (성공) resolve 함수가 호출된 상태
rejected 비동기 처리가 수행된 상태 (실패) reject 함수가 호출된 상태
settled 비동기 처리가 수행된 상태 (성공 또는 실패) resolve 또는 reject 함수가 호출된 상태

Promise 상태 변화

성공

  • resolve함수 호출, fullfilled 상태 변경

실패

  • reject 함수 호출, rejected 상태 변경

Promise의 에러 처리

Promise 객체의 후속 처리 메소드를 사용해 비동기 처리 결과에 대한 후속처리를 작업합니다. then()의 두번째 콜백함수로 전달되며 catch()를 사용해 에러를 처리할 수 있습니다.

2가지의 에러처리중 권장하는 방법은 catch() 방법입니다. 이유는 then()의 첫번째 콜백 함수 내부에서 발생한 오류는 잡아내지 못하기 때문인데 다음과 같은 코드의 결과를 통해 더 쉽게 이해할 수 있습니다.

 let demo1 = function demoFunc1() {
  return new Promise(function (resolve, reject) {
      resolve('hello Korea');
  });
}

demo1().then(function (result) {
    console.log(result);
    throw new Error("Error in first then()"); 
}, function (err) {
    console.log('catch의 에러 :', err);
});

스크린샷 2020-01-30 오전 1 41 39


let demo1 = function demoFunc1() {
  return new Promise(function (resolve, reject) {
      resolve('hello world');
  });    
}

demo1().then(function (result) {
  console.log(result);
  throw new Error("Error in first then()");
}).catch(function (err) {
    console.log('catch의 에러 :', err);
})

스크린샷 2020-01-30 오전 1 41 50


Reference

반응형

'Posts > JavaScript' 카테고리의 다른 글

Javascript 알아두면 좋은 개념 요약  (0) 2021.10.04