Callback, Promise, async/await

김철회·2022년 10월 20일
0

비동기

자바스크립트는 기본적으로 동기 언어이다. 호출된 순서대로 코드가 실행된다. 하지만 데이터 호출과 같은 함수는 데이터의 양에 따라서 시간이 오래걸릴 수 있다. 그렇다면 동기 언어인 자바스크립트에서는 비교적 빠르게 실행될 수 있는 함수가 데이터를 호출하는 함수보다 뒤에 있다면 데이터가 호출될 때까지 기다려야 하는 단점이 생길 수 있다.
비동기처리는 이러한 점을 보완한다. 시간이 오래 걸릴 수 있는 함수는 잠깐 뒤로 빼거나 나중에 처리할 수 있게 하는 것이 비동기이다.

Callback

const innerFunc = () => {
	console.log(1);
}

const func = (x) => {
  	console.log(2);
  	x();
}

func(innerFunc);

비동기 처리를 위해 처음에는 Callback함수를 사용했다. Callback함수는 함수의 인자로 함수를 받는 것이다.
위의처럼 하게 되면 원하는 순서대로 함수를 실행할 수 있다. 하지만 여기엔 함정이 있었으니.... 너무 많이 하다보니 Callback 지옥에 빠질 수 있다. 함수 안의 함수 안의 함수 안의 함수 안의.. like 러시아 인형

Promise

비동기 처리는 해야겠고... Callback지옥은 싫어서 es6에 Promise가 나타났다.
비동기 처리를 위해 사용하는 객체이다.

Promise는 3가지 상태값을 갖는다.

1) Pending 2) Fullfilled 3)Rejected

뜻에서 짐작할 수 있듯이, 대기/이행/실패의 상태이다.

풀어서 설명하면,
비동기 처리가 완료되지 않았다 => Pending
비동기 처리가 무사히 완료되었다 => Fulfilled
비동기 처리 중 실패허거나 오류가 생겼다 => Rejected

const testPromise = new Promise((resolve, reject) => {
	resolve("성공했당!");

});

testPromise
  .then((res) => {console.log(res)});
.catch((error)=>{conosole.log(error)});

1) testPromise라는 함수 앞에 new Promise를 붙여주고 인자로 resolve, reject를 받는다.
2) Promise객체에 의해 비동기 처리에 성공하면 resolve를 호출한다.
3) resolve의 "성공했당!" 을 반환하기 위해서 then 메서드를 사용해야 한다.
4) 그리고 에러가 나면 catch 메서드를 사용하면 된다.

then을 여러번 쓸 수도 있는데, 이를 프로미스 체이닝 이라고 한다.

하지만, 여기에도 단점이 있었으니... then 지옥이 생겨났다. 또한, then이 여러개 있을 때 catch문에서 에러가 표출 되는데 어느 then에서 에러가 났는지 정확히 확인할 수 없게 되었다.

이를 위해...

async/await

콜백지옥과 then 지옥을 해결하기 위해 async/await 님이 등장했다.
단, 이거 하나만 기억하고 가자! await는 async 안에서만 사용 가능하다.
그리고 async는 promise객체를 반환한다.


const testAsync = async () => {
	const testPromise = new Promise((resolve, reject) => {
	resolve("성공했당!");
 
});
  
  try {
  	const result = await testPromise;
    console.log(result);
  } catch (err) {
  	console.log(err);
  }

}

testAsync();

기본적으로 async/await는 Promise와 달리 에러를 다루지 못하기 때문에 try-catch문을 사용한다.
1) 사용할 함수 앞에다가 async만 써주면 된다. async가 붙어 있다는 것은, 앞으로 해당 함수를 비동기적으로 처리하겠다는 의미가 된다. async가 쓰여있다 = 이 함수는 비동기 처리할 것입니다.
2) try 안에서 함수가 차례대로 실행된다. await는 이름 그대로 기다린다는 의미이다.
뭘 기다릴까? Promise가 끝날 때까지 기다리겠다는 의미이다. 비동기처리는 오래 걸릴 수 있는 것을 기다리지 않고 나중에 하겠다는 의미로 쓸 수 있는데, async안에 await를 붙인 함수는 Promise 처리가 끝날 때 까지 다른 것을 하지 않고 잠깐 기다리겠다는 의미이다.
3) 그렇기 때문에 try 안에서 console.log(result)가 먼저 실행되지 않고, await testPromise의 반환 값을 담은 result를 기다렸다가 result의 값을 console.log가 실행되는 것이다.

  • testPromise를 비동기 처리하기 위해 new Promise 객체를 붙여줘도 되지만, 아래처럼 async만 써서 해당 함수를 만들어줘도 된다. async를 함수 앞에 쓴다는 것은 Promise 객체로 해당 함수를 반환하겠다는 의미가 되기 때문이다.

더 간단한 예제로는 다음과 같이 쓸 수 있다.

	const testAsync = async () => {
    	console.log(1);
    }
    
    testAsync(); 

1) console 창에 1을 나타내는 비동기 함수 testAsync를 호출하겠다는 의미이다.

profile
안녕하세요!

0개의 댓글