본문 바로가기

JavaScript

[#JavaScript] 자바스크립트 비동기 처리와 콜백 함수, Promise 프로미스, Async await

반응형

 

 

 

 

 

① 동기와 비동기

 

⑴ 동기

요청과 응답이 동시에 일어난다 설계가 간단하고 직관적이지만 응답이 있을 때까지 대기해야 한다 작업은 직렬적, 순차적으로 실행되며 현재 실행 중인 작업이 있다면 이후 작업은 대기하게 된다

 

function sync1() {
  console.log(1)
}

function sync2() {
  console.log(2)
}

function sync3() {
  console.log(3)
}

sync1()
sync2()
sync3()

// 1, 2, 3 출력 

 

⑵ 비동기

요청과 응답이 동시에 일어나지 않는다 응답이 오기 전까지 다른 요청이나 작업이 가능하다 작업은 병렬적으로 실행되며 실행 중인 작업이 종료되지 않은 상태라고 해도 대기 없이 다음 작업이 실행된다

 

function async1() {
  setTimeout(function() {
    console.log(1)
  }, 1000)
}

function sync1() {
  console.log(2)
}

function sync2() {
  console.log(3)
}

async1()
sync1()
sync2()

// 2, 3, 1 출력

 

 

② 콜백 함수

콜백 함수는 함수 안에서 어떤 특정한 시점에 호출되는 함수를 말한다 보통 콜백 함수는 함수의 매개변수로 전달하여 특정 시점에서 콜백 함수를 호출한다

 

function async1(a) {
   setTimeout( function() {
      console.log(1)
      a()
   }, 1000)
}

function sync1(a) {
   console.log(2)
   a()
}

function sync2() {
   console.log(3)
}

async1(function(async1Result) {
   sync1(function(sync1Result) {
      sync2()
  })
})

// 1, 2, 3 출력

 

하지만 콜백 함수는 비동기 작업이 길어질수록 콜백이 깊어지고, 함수 내에서 if문 분기와 에러 핸들링이 어렵다

 

 

 

③ Promise

콜백 함수 지옥을 해결하기 위해 등장했다 .then()으로 비동기 작업을 연결하고, .catch()로 에러를 핸들링한다 Java Script 비동기 처리에 사용되는 객체다

 

⑴ Promise의 상태

  • Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
  • Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환한 상태
  • Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

 

Pending(대기)

new Promise();

콜백 함수 호출 가능하다 콜백 함수의 인자 resolve, reject

new Promise(function(resolve, reject) {
   ...			
}

 

 

Fulfilled(이행)

new Promise(function(resolve, reject) {
   resolve();
});
function getNum() {
   return new Promise(function(resolve, reject) {
      var num = 10;
      resolve(num);
   });
}

getNum()
   .then(function(resolveNum) {
      console.log(resolveNum);
});

getNum()의 결과 값 num을 resolveNum으로 받아온다

 

 

Rejected(실패)

new Promise(function(resolve, reject) {
   reject();
});
function getNum() {
   return new Promise(function(resolve, reject) {
      reject(new Error("failed"));
   });
}

getNum()
   .then()
   .catch(function(err) {
      console.log(err);
});

 

Pending+Fulfilled+Rejected

function getNum() {
   return new Promise(function(resolve, reject) {
      $.get('url/list', function(response) {
         if(response) {
            resolve(response);
         }
         reject(new Error("failed"));
      })
   });
}

getNum()
   .then(function(num) {
      console.log(num);
   })
   .catch(function(err) {
      console.log(err);
   });

 

 

 

function aync1() {
   return new Promise( function(resolve) {
      setTimeout( function() {
         console.log(1)
         resolve()
      }, 300)
   })
}

function aync2() {
   return new Promise(function (resolve) {
      setTimeout(function() {
         console.log(2)
         resolve()
      }, 100)
   })
}

function aync3() {
   return new Promise(function (resolve) {
      setTimeout(function() {
         console.log(3)
         resolve()
      }, 100)
   })
}

aync1()
aync2()
aync3()

// 2, 3, 1 출력
async1()
  .then(function(result) {
    return async2()
  })
  .then(function(result) {
    return async3()
  })
  .catch(function(error) {
    console.log(error)
  });
  
// 1, 2, 3 출력

하지만 Promise도 콜백 함수와 같이 then()이 깊어질 수 있고, 함수 내에서 if문 분기와 에러 핸들링이 어렵다

 

 

 

④ Async await

콜백 함수, Promise의 단점을 해결하기 위해 ES7에 등장했다 함수 내에서 if문 분기와 에러 핸들링이 가능하고 Promise와 다르게 에러 추적도 용이하다 함수 앞에 async라는 단어가 온다 await 키워드는 오직 async로 정의된 함수의 내부에서만 사용할 수 있다 모든 async 함수는 암묵적으로 Promise를 반환하고, Promise가 함수로부터 반환할 값을 resolve 한다 

async await에서 발생한 에러 스택은 에러를 포함한 함수를 가리킨다 ex) `Error: failed at async3 (index.js:7:9)`

 

 

async function async1() {
   return new Promise(function(resolve) {
      setTimeout(function() {
         resolve(10);
      }, 300)
   })
}

async function async2() {
  const result = await async1();
  console.log(result)			// 10 출력
}

async function async3() {			// try-catch
   let result;
   try {
      response = await async1()
   } catch(error) {
      console.log(error);
   }
   return result;
};

 

 

 

 

 

 

 

 

반응형