Javascript async/await

fgStudy·2022년 5월 26일
1

자바스크립트

목록 보기
24/26
post-thumbnail

async await 정의

  • ES8에 도입된 비동기 처리 키워드
  • 프로미스를 기반으로 동작
  • 후속처리 메서드인 then/catch/finally에 콜백 함수를 전달해서 비동기 처리 결과를 처리할 필요 없이 동기 처리처럼 프로미스가 처리 결과를 반환하도록 구현할 수 있다.

async await 예제

const fetch = require('node-fetch');

async function fetchTodo() {
  const url = 'https://jsonplaceholder.typicode.com/todos/1';

  const response = await fetch(url);
  const todo = await response.json();
  console.log(todo);
  // {userId: 1, id: 1, title: 'delectus aut autem', completed: false}
}

fetchTodo();

async 함수

  • await 키워드는 반드시 async 함수 내부에서 사용한다.
  • async 함수는 언제나 프로미스를 반환한다.
// async 함수 선언문
async function foo(n) { return n; }
foo(1).then(v => console.log(v)); // 1

// async 함수 표현식
const bar = async function (n) { return n; };
bar(2).then(v => console.log(v)); // 2

// async 화살표 함수
const baz = async n => n;
baz(3).then(v => console.log(v)); // 3

// async 메서드
const obj = {
  async foo(n) { return n; }
};
obj.foo(4).then(v => console.log(v)); // 4

// async 클래스 메서드
class MyClass {
  async bar(n) { return n; }
}
const myClass = new MyClass();
myClass.bar(5).then(v => console.log(v)); // 5
  • 클래스의 constructor 메서드는 async 메서드가 될 수 없다. 클래스의 constructor 메서드는 인스턴스를 반환해야 하지만, async 함수는 언제나 프로미스를 반환해야 한다.
// 클래스 constructor 메서드는 async 메서드가 될 수 없다.
class MyClass {
	async constructor() {}
  	// SyntaxError: Class constructor may not be an async method
}

const myClass = new MyClass();


await 키워드

  • await 키워드는 프로미스가 settled 상태(비동기 처리가 수행된 상태)가 될때까지 대기하다가 settled 상태가 되면 프로미스가 resolve한 처리 결과를 반환한다.

  • await 키워드는 모든 프로미스에 사용해야 한다.

async function foo() {
  const res = await Promise.all([
    new Promise(resolve => setTimeout(() => resolve(1), 3000)),
    new Promise(resolve => setTimeout(() => resolve(2), 2000)),
    new Promise(resolve => setTimeout(() => resolve(3), 1000))
  ]);

  console.log(res); // [1, 2, 3]
}

foo(); // 약 3초 소요된다.

아래 bar 함수는 앞선 비동기 처리의 결과를 가지고 다음 비동기 처리를 수행해야 한다. 따라서 비동기 처리의 처리 순서가 보장되어야 하므로 모든 프로미스에 await 키워드를 써서 순차적으로 처리하자.

async function bar(n) {
  const a = await new Promise(resolve => setTimeout(() => resolve(n), 3000));
  // 두 번째 비동기 처리를 수행하려면 첫 번째 비동기 처리 결과가 필요하다.
  const b = await new Promise(resolve => setTimeout(() => resolve(a + 1), 2000));
  // 세 번째 비동기 처리를 수행하려면 두 번째 비동기 처리 결과가 필요하다.
  const c = await new Promise(resolve => setTimeout(() => resolve(b + 1), 1000));

  console.log([a, b, c]); // [1, 2, 3]
}

bar(1); // 약 6초 소요된다.


에러 처리

  • async/await에서 에러 처리는 try ... catch문을 사용한다.
  • async 함수 내에서 catch 문을 사용해서 에러 처리를 하지 않으면 async 함수는 발생한 에러를 reject하는 프로미스를 반환한다.
  • 따라서 catch 후속 메서드를 이용해 에러를 캐치할 수 있다.
    (catch 메서드의 콜백 함수는 프로미스가 rejected 상태인 경우에만 호출되므로)
const fetch = require('node-fetch');

const foo = async () => {
  try {
    const wrongUrl = 'https://wrong.url';

    const response = await fetch(wrongUrl);
    const data = await response.json();
    console.log(data);
  } catch (err) {
    console.error(err); // TypeError: Failed to fetch
  }
};

foo();
profile
지식은 누가 origin인지 중요하지 않다.

0개의 댓글