본문 바로가기
front-end/javascript

Javascript 동기와 비동기 callback부터 async&await

by MOOB 2019. 8. 23.

javascript 동기와 비동기

 

자바스크립트는 싱글 스레드 언어이기 때문에 효율적인 작업 처리를 위해 비동기 처리를 사용한다.

  • 동기 : 요청 처리가 완료 된 후 다음 요청을 처리 하는 방식으로 이전 요청을 처리하는 시간이 다음 요청에 영향을 준다. (요청과 응답이 같은 시간대에 있다. 일반적으로 작성한 코드는 보통 동기 방식으로 처리된다.
console.log("1");
console.log("2");
console.log("3");
  • 비동기 : 하나의 요청 처리가 완료되기 전에 다음 요청을 처리 하는 방식. 요청과 응답이 다른 시간대에 일어날 수 있다.

자바스크립트의 비동기 처리의 대표적 방식은 setTimeOut, callback, promise 등이 있다. 각각 일장일단이 있지만 최근 ES8에서 awaitasync가 이 문제점을 크게 개선했다.

callback 함수

callback함수는 다른 함수의 인자로 사용되거나 이벤트에 의해 호출되어지는 함수를 말한다. 즉 어떤 함수의 요청이 처리되어 나온 그 응답(값)을 call back하여 다음 함수에서 사용할 수 있는 것을 callback이라 부른다.

callback함수는 비동기적으로 작성된 함수들을 사용자의 편의에 따른 순서로 동기처리가 가능하게 한다.

const arr = [0,1,2,3,4,5];

(arr.forEach(function(element){
//function이 for Each의 인자로 활용되고 있음
    console.log(element);
})();

그러나 callback함수를 너무 많이 중첩하여 사용하면 가독성이 크게 떨어지고 함수끼리 서로 꼬여 에러가 발생할 확률이 커진다.

setTimeOut

setTimeOut은 보통 호출될 콜백함수와 지연 시간 두가지 인자를 설정하여 사용한다. 다음 함수는 3초 후 setTimeOut 내부의 함수에 의해 console에 Works!라는 글자가 찍히는 함수다.

setTimeout(function() {
 console.log('Works!');
}, 3000);

이와 같은 함수를 시간 지연 함수라 부르는데 setTimeOut외에도 clearTimeOut, setInterval등이 있다.

Promise함수

promise 함수는 앞서 말한 callback의 문제점을 해결하기 위해 나온 개념이다. 콜백을 예측 가능한 패턴으로 사용할 수 있도록 도와주며 callback내의 프로미스 객체를 활용해 성공, 실패, 오류 등 다양한 상황에 따른 후속처리를 가능하게 한다.

function test(){
resolve(); // second, 밑 함수로 넘어감
console.log("hi"); // first
}

test().then(function({
console.log("done"); // resolve(); 성공시
}, .then(function(){
console.log("failed"); //resolve(); 실패시
})

위 함수와 같이 함수의 처리 순서에 따라 callback을 작성할 수 있어 유지보수에 굉장히 적합하다. resolve()외에 rejected()를 넣어 각 상황에 따라 다른 함수로 처리되게 할 수도 있다. 또한 클로저 함수로 표헌 할 수도 있음 (추후추가)

await & async

asyncawait은 위의 어떤 함수보다도 직관적이다. 동기 함수 앞에는 async를 붙이고 비동기 함수 앞에는 await을 붙이면 된다. 단 async의 뒤에는 반드시 promise를 반환해야 하며 awaitasync 함수 안에서만 사용할 수 있다.

const funcPromise = async () => {
  return 'hello!';
};
funcPromise().then((result) => {
// then() 성공, catch() 실패 제어
  console.log(result); // 'hello'
});

await 함수의 사용

앞서 말했듯 await함수는 async 함수 내에서만 사용 가능하다.

const msg = async function() {
  const msg = await thenFunc();
  console.log('Message:', msg);
}
try/catch 사용한 예제
function yayOrNay() {
  return new Promise((resolve, reject) => {
    const val = Math.round(Math.random() * 1); // 0 or 1, at random

    val ? resolve('Hello!') : reject('Nope');
  });
}

async function msg() {
  try {
    const msg = await yayOrNay();
    console.log(msg);
  } catch(err) {
    console.log(err);
  }
}

댓글