상세 컨텐츠

본문 제목

[자바스크립트] 동기와 비동기, 콜백 함수, Promise, async, await

자바스크립트

by front-hyun 2023. 4. 13. 19:03

본문

동기와 비동기

동기

  • 동시에 일어나는 요청과 결과가 동시에 일어난다는 약속입니다.
  • 작업이 순차적으로 실행됩니다.
  • 여러가지 작업을 함께 수행할 수 없으며, 어떤 작업이 수행 중이면 다음 작업은 대기 상태가 됩니다.
console.log("start");
console.log("end");

 

비동기

  • 동시에 일어나지 않는 요청과 결과가 동시에 일어나지 않을 거라는 약속입니다.
  • 작업의 병렬적 실행입니다.
  • 어떤 작업을 수행하는 중에도 다른 작업을 수행할 수 있으며, 여러 작업을 동시에 수행할 수 있습니다. 

 

비동기와 동기 비교

  장점 단점
동기 설계가 쉽고 직관적입니다. 결과가 주어질 때까지 아무것도 하지 목하고 대기해야 합니다.
비동기 여러개의 작업을 동시에 수행 가능하고,
효율적인 자원 사용 가능합니다.
설계가 복잡합니다.

 

비동기 처리 방식의 문제점

  • 작업 b는 작업 a가 실행 완료된 뒤 수행되어야 하는데, 작업 a가 얼마나 많은 시간이 걸릴지 실행하기 전에 알 수 없습니다.
  • 비동기 처리를 기본으로 하면서도 일부 구간에서 순차적인 처리가 필요한 경우가 존재합니다.

콜백 함수

콜백함수 vs 기본함수

  • 콜백함수를 이해시키기 위해 먼저 cry, sing, dance 를 하는 함수를 먼저 생성해줍니다.
  • (아래의 내용 [1.일반함수] , [2.콜백함수] 에서 모두 사용하는 함수들입니다.)
function cry() {
console.log("cry");
}
 

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

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

 

기본함수

// 1. 기본 함수
// 기분 좋을때 춤을 추고 싶으면 sing()함수에 dance()로 변경해야함
function checkMood(mood) {
      if (mood === "good") {
             sing();
      } else {
             cry();
      }
}
 
checkMood("good");
checkMood("sad");

콜백함수

// 2. 콜백함수 (함수를 매개변수로 넣어줌)
function checkMoodCallBack(mood, goodCallback, badCallback) {
if (mood === "good") {
goodCallback();
} else {
badCallback();
}
}
 

checkMoodCallBack("good", dance, cry);
checkMoodCallBack("Not bad", dance, sing);

 

  • 함수를 함수의 인수(값)로 전달하고, 인수로 전달함 함수를 나중에(필요할 때) 호출하는 것입니다.
  • 유연한 비동기 처리를 위한 하나의 패턴입니다.
  • 특정 로직이 끝났을 때 원하는 동작을 실행시킬 수 있습니다.
  • "good"일때 dance를 하도록,  checkMoodCallBack에서 호출할 함수를 지정할 수 있다. 이렇게 사용할 함수들 마져 선택해서 사용하는 것이 바로 콜백함수이다.

콜백 지옥

  • 비동기 처리 로직의 처리 순서를 보장하기 위해 콜백 함수를 연속해서 사용할 때 발생하는 문제입니다.

 

Promise

  • 자바스크립트 비동기 처리에 사용되는 객체입니다.
  • 콜백 함수를 사용할 때 나타나는 문제점인 콜백 지옥과 에러 처리가 곤란하다는 점을 해결하기 위해 제안되었습니다.

promise 생성

const promise = new Promise((resolve, reject) => {
//executor
});
  • executor: Promise가 만들어질 때 자동으로 실행되는 함수입니다.
  • resolve, reject: 자바스크립트에서 자체 제공하는 콜백입니다.
  • resolve(value) - Promise 성공 시 그 결과를 나타내는 value와 함께 호출됩니다.
  • reject(error) - 에러 발생 시 에러 객체를 나타내는 error와 함께 호출됩니다.

 

promise의 3가지 상태

  • promise는 생성되고 종료될 때까지 3가지 상태를 가집니다.
  • Pending(대기): 비동기 처리 로직이 아직 완료되지 않은 상태
  • Fulfilled(이행): 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
  • Rejected(실패): 비동기 처리가 실패하거나 오류가 발생한 상태
//처음 Promise 객체 
state: "pending", result: undefined

//Promise가 성공한 경우
state: "fulfilled", result: value

//Promise가 실패한 경우
state: "rejected", result: error

 

 

promise의 후속 처리 메소드 -  then

promise.then(
function(result){ //결과를 다룹니다.}
function(error){ //에러를 다룹니다. }
);
  • 실패: 비동기 처리가 실패하거나 오류가 발생한 상태
  • 파일 업로드 작업이 실패 or 성공인지
  • then은 두 개의 인수를 받을 수 있습니다.
  • 프로미스가 성공적으로 처리된 경우만 다루고 싶다면 then에 인수를 하나만 전달하면 된다.

-> 첫 번째 인수: 프로미스가 이행되었을 때 실행되는 함수

-> 두 번째 인수: 프로미스가 거부되었을 때 실행하는 함수

 

promise의 후속 처리 메소드 -  catch

  • 작업이 거부된 경우(에러 발생)만 다루고 싶을 때 사용합니다.

promise의 후속 처리 메소드 -  finally

  • 프로미스가 처리되면(이행 또는 거부) 항상 실행된다.

promise chaining

  • 후속 처리 메소드(then, catch)를 체이닝하여서 여러 개의 프로미스를 연결하여 사용함으로써 해결합니다.
Promise Callback
흐름이 자연스럽다. 비동기 함수 처리 결과에 따라 그다음에 무엇을 할지 코드를 작성하면 된다. 비동기 처리 함수를 호출할 때, 콜백 함수가 미리 정의되어 있어야 한다.
비동기 함수 처리 결과가 프로미스 객체에 저장되기 때문에 코드 작성이 용이해진다. 비동기 함수 처리 결과가 필요할 때마다 콜백 함수를 호출해야 한다.
원하는 만큼 then 메소드를 호출할 수 있다. 하나의 콜백 함수만 호출할 수 있다.

 

 

asunc/await

  • Promise 객체를 좀 더 쉽게 다룰 수 있게 고안된 문법입니다.
  • 비동기 작업의 순차 처리를 일반 순차 프로그래밍처럼 할 수 있습니다.

async

  • 사용법: function 앞에 async 키워드를 붙여줍니다.
  • async를 붙임 함수는 항상 promise를 반환합니다.

await

  • 사용법: 함수의 앞부분에 async 키워드를 추가하고, 해당 함수 내부에서 Promise의 앞부분에 await 키워드를 붙여줍니다.
  • Promise가 끝날 때까지 기다리고, 결과 값을 특정 변수에 담을 수 있습니다. 
  • 기다리는 동안 엔진이 다른 일을 할 수 있기 때문에 CPU 리소스가 낭비되지 않습니다.

관련글 더보기