46장 async/await
async/await
- 간단하고 가독성 좋게 비동기 처리를 동기 처리처럼 동작하도록 구현
- 프로미스의 then/catch/finally에 콜백 함수를 전달해서 비동기 처리 결과를 후속 처리할 필요 없이 마치 동기 처리처럼 프로미스를 사용할 수 있음.
- 다시 말해, 프로미스의 후속 처리 메서드 없이 마치 동기 처리처럼 프로미스가 처리 결과를 반환하도록 구현할 수 있음.
46-14
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();
1 ) async 함수
- await 키워드는 반드시 async 함수 내부에서 사용해야함.
- 언제나 프로미스를 반환.
46-15
// 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
2 ) await 키워드
- await 키워드는 프로미스가 settled 상태가 될 때까지 대기하다가 settled 상태가 되면 프로미스가 resolve한 처리 결과를 반환함.
- 반드시 프로미스 앞에서 사용해야함.
46-17
const fetch = require('node-fetch');
const getGithubUserName = async id => {
const res = await fetch(`https://api.github.com/users/${id}`); // ①
const { name } = await res.json(); // ②
console.log(name); // Ungmo Lee
};
getGithubUserName('ungmo2');
- 프로미스가 settled 상태가 되면 프로미스가 resolve한 처리 결과가 res 변수에 할당됨.
46-18
async function foo() {
const a = await new Promise(resolve => setTimeout(() => resolve(1), 3000));
const b = await new Promise(resolve => setTimeout(() => resolve(2), 2000));
const c = await new Promise(resolve => setTimeout(() => resolve(3), 1000));
console.log([a, b, c]); // [1, 2, 3]
}
foo(); // 약 6초 소요된다.
46-19
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초 소요된다.
46-20
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초 소요된다.
3 ) 에러 처리
- 비동기 함수의 콜백 함수를 호출한 것은 비동기 함수가 아니기 때문에 try … catch 문을 사용해 에러를 캐치할 수 없음.
46-21
try {
setTimeout(() => { throw new Error('Error!'); }, 1000);
} catch (e) {
// 에러를 캐치하지 못한다
console.error('캐치한 에러', e);
}
- async/await 에서 에러 처리는 try … catch 사용 가능.
46-22
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();
- async 함수 내에서 catch 문을 사용해서 에러 처리를 하지 않으면 async 함수는 발생한 에러를 reject하는 프로미스를 반환함.
46-23
const fetch = require('node-fetch');
const foo = async () => {
const wrongUrl = '<https://wrong.url>';
const response = await fetch(wrongUrl);
const data = await response.json();
return data;
};
foo()
.then(console.log)
.catch(console.error); // TypeError: Failed to fetch
'JS' 카테고리의 다른 글
모던 자바스크립트 Deep Dive - 모듈 (0) | 2024.02.20 |
---|---|
모던 자바스크립트 Deep Dive - 에러 처리 (0) | 2024.02.19 |
모던 자바스크립트 Deep Dive - 프로미스 (0) | 2024.02.16 |
모던 자바스크립트 Deep Dive - REST API (0) | 2024.02.15 |
모던 자바스크립트 Deep Dive - Ajax (0) | 2024.02.14 |
댓글