2023. 3. 1. 20:49ㆍFE/JavaScript
0. 참고자료
1. async
async function
선언은 AsyncFunction
객체를 반환하는 하나의 비동기 함수를 정의합니다.
비동기 함수는 이벤트 루프를 통해 비동기적으로 작동하는 함수로, 암시적으로 Promise
를 사용하여 결과를 반환합니다. (출력값이 Promise 객체다.)
그러나 비동기 함수를 사용하는 코드의 구문과 구조는, 표준 동기 함수를 사용하는 것과 많이 비슷합니다. (특장점!)
비동기 함수를 사용하는 그 어떤 방식들보다 단순하고 직관적이다.
2. await
await
연산자는 Promise
를 기다리기 위해 사용됩니다. 연산자는 async function
내부에서만 사용할 수 있습니다.
await
문은 Promise
가 fulfill되거나 reject
될 때까지 async
함수의 실행을 일시 정지하고, Promise
가 fulfill되면 async
함수를 일시 정지한 부분부터 실행합니다.
이때 await
문의 반환값은 Promise
에서 fulfill된 값이 됩니다.
만약 Promise
가 reject
되면, await
문은 reject
된 값을 throw
합니다.
예제 1) async & await
// 1. Promise
function getUm(){
return new Promise((res, rej)=>{
const Um ='엄';
setTimeout(()=>{
res(Um);
}, 2000);
});
}
getUm().then( Um => {
console.log(Um);
});
Promise객체를 이용해서 비동기 함수를 처리했다.
이걸 async
와 await
를 사용해서 바꿔보자.
// 2. async & await
function delay(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
async function getJunSik() {
const name = '준.식.';
await delay(2000);
console.log(name); // 10
}
getJunSik();
예제 2)
이번에는 엄. 준. 식.을 따로따로 받아와서 합친 다음 콘솔로 출력하겠다.
function delay(ms) {
return new Promise((resolve)=>{
// setTimeout(()=>{resolve();}, ms);
setTimeout(resolve, ms);
});
}
// 엄
async function getUm(){
await delay(2000);
return '엄.';
}
// 준
async function getJun(){
await delay(2000);
return '준.';
}
//식
async function getSik(){
await delay(2000);
return '식';
}
// 어떻게 사람 이름이...
async function printUJS(){
const Um = await getUm();
const Jun = await getJun();
const Sik = await getSik();
console.log(Um + Jun + Sik);
}
printUJS();
잘 작동한다.
겁나 느리다.
대략 6초가 소요된다.
async function printUJS(){
const Um = await getUm();
const Jun = await getJun();
const Sik = await getSik();
console.log(Um + Jun + Sik);
}
비동기 함수 printUJS
안에서 await
키워드를 사용할 수 있다.
Um, Jun, Sik 각각이 순서대로 2초간 delay를 받고 출력된다.
3. 병렬처리
async function printUJS(){
const Um = await getUm();
const Jun = await getJun();
const Sik = await getSik();
console.log(Um + Jun + Sik);
}
Um, Jun, Sik 각각이 순서대로 2초간 delay를 받고 출력된다고 했다.
Um, Jun, Sik은 각각이 모두 비동기 함수인데 우리가 굳이 순차적으로 실행시켜 시간을 낭비할 이유가 없다.
그렇기에 동시에 비동기적으로 처리하고 그 값을 모아서 출력하게 해 보자.
Promise객체는 생성되는 순간부터 동작한다.
이런 성질을 이용하면 Um, Jun, Sik이 동시에 동작하도록 할 수 있다.
async function printUJS(){
const UmPromise = getUm();
const JunPromise = getJun();
const SikPromise = getSik();
Um = await UmPromise;
Jun = await JunPromise;
Sik = await SikPromise;
console.log(Um + Jun + Sik);
}
printUJS();
async function
을 먼저 실행해서 작업하도록 한 후 await
로 기다렸다가 받으면 된다.
이것을 멋있는 말로 병렬처리라고 한다.
가. Promise.all
똑같은 병렬처리를 더 멋있고 간편하게 구현하는 방법을 알아보자.
// Promise.all
async function printUJS2(){
return Promise.all([getUm(),getJun(),getSik()])
.then(name => name.join(''));
}
printUJS2().then(console.log);
// printUJS2().then(name =>{console.log(name)});
return Promise.all([getUm(),getJun(),getSik()])
: 배열로 주어진 모든 프로미스가 이행하거나, 한 프로미스가 거부될 때까지 대기하는 새로운 프로미스를 반환한다. Um, Jun, Sik이 모두 이행되면 결괏값을 배열로 반환한다..then(name => name.join(''));
: 배열의 모든 요소를 연결해 하나의 문자열로 만든다. 비워두면,
가 구분자로 사용된다.printUJS2().then(console.log);
: 입력값이 같은 경우 생략가능하다.
Promise.alll
외에도 사용할 수 있는 메서드는 다음과 같다.
잘 사용하면 병렬로 작업을 수행하고 또 제어하는 것에 큰 도움이 될 것이다.
Promise.allSettled(iterable)
: 주어진 모든 프로미스가 처리(이행 또는 거부)될 때까지 대기하는 새로운 프로미스를 반환합니다.Promise.allSettled()
가 반환하는 프로미스는 매개변수로 제공한 모든 프로미스 각각의 상태와 값(또는 거부 사유)을 모아놓은 배열로 이행합니다.Promise.any(iterable)
: 주어진 모든 프로미스 중 하나라도 이행하는 순간, 즉시 그 프로미스의 값으로 이행하는 새로운 프로미스를 반환합니다.
: 즉, 어떤 프로미스가 성공하면Promise.any()
는 성공하고, 모든 프로미스가 거부되면AggregateError
를 반환합니다.Promise.race(iterable)
: 주어진 모든 프로미스 중 하나라도 처리될 때까지 대기하는 프로미스를 반환합니다. 반환하는 프로미스가 이행한다면, 매개변수의 프로미스 중 첫 번째로 이행한 프로미스의 값으로 이행합니다. 반환하는 프로미스가 거부된다면, 매개변수의 프로미스 중 거부된 첫 프로미스의 사유를 그대로 사용합니다.
: 가장 먼저 성공(resolve) 또는 거부(reject)된 프로미스가 있는 경우, 해당 결과가 반환됩니다.
'FE > JavaScript' 카테고리의 다른 글
[JavaScript] BOM, DOM (0) | 2024.01.14 |
---|---|
[JavaScript] destructuring operator (0) | 2023.03.27 |
[JavaScript] var과 let (0) | 2023.02.10 |
2022-08-22 JS_6 (0) | 2022.08.22 |
2022-08-18 JS_5 (배열, 반복문, 콘솔, 함수) (0) | 2022.08.19 |