JavaScript에서 Async/Await 함수 탐색
소개
Promise는 코드의 비동기성을 순차적으로 처리하는 더 쉬운 방법을 제공합니다. 우리의 두뇌가 비동기성을 효율적으로 처리하도록 설계되지 않았다는 점을 고려하면 이것은 매우 반가운 추가 사항입니다. ES2017(ES8)에 새로 추가된 Async/await 함수는 백그라운드에서 비동기 작업을 수행하면서 완전히 동기식으로 보이는 코드를 작성할 수 있도록 도와줍니다.
비동기 함수를 사용하여 달성한 기능은 약속을 생성기와 결합하여 다시 만들 수 있지만 비동기 함수는 추가 상용구 코드 없이 필요한 것을 제공합니다.
간단한 예
다음 예제에서는 먼저 2초 후에 🤡
값으로 확인되는 약속을 반환하는 함수를 선언합니다. 그런 다음 async 함수를 선언하고 메시지를 콘솔에 기록하기 전에 해결될 약속을 await합니다.
function scaryClown() {
return new Promise(resolve => {
setTimeout(() => {
resolve('🤡');
}, 2000);
});
}
async function msg() {
const msg = await scaryClown();
console.log('Message:', msg);
}
msg(); // Message: 🤡 <-- after 2 seconds
await
는 약속이 해결되거나 거부되기를 기다리는 데 사용되는 새로운 연산자입니다. 비동기 함수 내에서만 사용할 수 있습니다.
비동기 함수의 힘은 여러 단계가 관련되어 있을 때 더욱 분명해집니다.
function who() {
return new Promise(resolve => {
setTimeout(() => {
resolve('🤡');
}, 200);
});
}
function what() {
return new Promise(resolve => {
setTimeout(() => {
resolve('lurks');
}, 300);
});
}
function where() {
return new Promise(resolve => {
setTimeout(() => {
resolve('in the shadows');
}, 500);
});
}
async function msg() {
const a = await who();
const b = await what();
const c = await where();
console.log(`${ a } ${ b } ${ c }`);
}
msg(); // 🤡 lurks in the shadows <-- after 1 second
그러나 주의할 점은 위의 예에서 각 단계는 순차적으로 수행되며 각 추가 단계는 계속하기 전에 해결하거나 거부하기 전에 단계를 기다립니다. 대신 단계를 병렬로 수행하려면 Promise.all을 사용하여 모든 약속이 이행될 때까지 기다리면 됩니다.
// ...
async function msg() {
const [a, b, c] = await Promise.all([who(), what(), where()]);
console.log(`${ a } ${ b } ${ c }`);
}
msg(); // 🤡 lurks in the shadows <-- after 500ms
Promise.all은 전달된 약속이 모두 해결되면 해결된 값이 있는 배열을 반환합니다.
위의 코드에서 우리는 코드를 간결하게 만들기 위해 멋진 배열 구조 분해를 사용합니다.
약속-반환
비동기 함수는 항상 약속을 반환하므로 다음은 원하는 결과를 생성하지 못할 수 있습니다.
async function hello() {
return 'Hello Alligator!';
}
const b = hello();
console.log(b); // [object Promise] { ... }
반환되는 것은 약속이므로 대신 다음과 같이 할 수 있습니다.
async function hello() {
return 'Hello Alligator!';
}
const b = hello();
b.then(x => console.log(x)); // Hello Alligator!
...또는 이것만:
async function hello() {
return 'Hello Alligator!';
}
hello().then(x => console.log(x)); // Hello Alligator!
다른 형태
지금까지 예제에서 비동기 함수를 함수 선언으로 보았지만 비동기 함수 표현식과 비동기 화살표 함수도 정의할 수 있습니다.
비동기 함수 표현식
다음은 첫 번째 예제의 비동기 함수이지만 함수 표현식으로 정의됩니다.
const msg = async function() {
const msg = await scaryClown();
console.log('Message:', msg);
}
비동기화살표 함수
동일한 예가 다시 한 번 있지만 이번에는 화살표 함수로 정의됩니다.
const msg = async () => {
const msg = await scaryClown();
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('Lucky!!') : reject('Nope 😠');
});
}
async function msg() {
try {
const msg = await yayOrNay();
console.log(msg);
} catch(err) {
console.log(err);
}
}
msg(); // Lucky!!
msg(); // Lucky!!
msg(); // Lucky!!
msg(); // Nope 😠
msg(); // Lucky!!
msg(); // Nope 😠
msg(); // Nope 😠
msg(); // Nope 😠
msg(); // Nope 😠
msg(); // Lucky!!
비동기 함수가 항상 약속을 반환한다는 점을 감안할 때 일반적으로 catch 문을 사용하는 것처럼 처리되지 않은 오류를 처리할 수도 있습니다.
async function msg() {
const msg = await yayOrNay();
console.log(msg);
}
msg().catch(x => console.log(x));
이 동기식 오류 처리는 약속이 거부된 경우뿐만 아니라 실제 런타임 또는 구문 오류가 발생한 경우에도 작동합니다. 다음 예에서는 msg 함수를 호출하여 두 번째로 toUpperCase 메서드가 없는 number 값을 전달합니다. 프로토타입 체인. try…catch 블록도 해당 오류를 포착합니다.
function caserUpper(val) {
return new Promise((resolve, reject) => {
resolve(val.toUpperCase());
});
}
async function msg(x) {
try {
const msg = await caserUpper(x);
console.log(msg);
} catch(err) {
console.log('Ohh no:', err.message);
}
}
msg('Hello'); // HELLO
msg(34); // Ohh no: val.toUpperCase is not a function
Promise 기반 APIS를 사용한 비동기 함수
Fetch API 입문서에서 살펴본 것처럼 약속 기반 웹 API는 비동기 함수를 위한 완벽한 후보입니다.
async function fetchUsers(endpoint) {
const res = await fetch(endpoint);
let data = await res.json();
data = data.map(user => user.username);
console.log(data);
}
fetchUsers('https://jsonplaceholder.typicode.com/users');
// ["Bret", "Antonette", "Samantha", "Karianne", "Kamren", "Leopoldo_Corkery", "Elwyn.Skiles", "Maxime_Nienow", "Delphine", "Moriah.Stanton"]
브라우저 지원:
결론
Async/await 함수 이전에는 많은 비동기 이벤트에 의존하는 JavaScript 코드(예: API를 많이 호출하는 코드) 일부에서 \콜백 지옥\이라고 하는 상황에 처했습니다. 읽고 이해하기 매우 어려웠던 함수 및 콜백.
Async 및 await를 사용하면 훨씬 더 명확하게 읽는 비동기 JavaScript 코드를 작성할 수 있습니다.