[Javascript] async & await

2023. 3. 1. 20:49FE/JavaScript

0. 참고자료

 

 


1. async

 

 

async function - JavaScript | MDN

async function 선언은 AsyncFunction객체를 반환하는 하나의 비동기 함수를 정의합니다. 비동기 함수는 이벤트 루프를 통해 비동기적으로 작동하는 함수로, 암시적으로 Promise를 사용하여 결과를 반환

developer.mozilla.org

 

async function 선언은 AsyncFunction객체를 반환하는 하나의 비동기 함수를 정의합니다.

 

비동기 함수는 이벤트 루프를 통해 비동기적으로 작동하는 함수로, 암시적으로 Promise를 사용하여 결과를 반환합니다. (출력값이 Promise 객체다.)

 

그러나 비동기 함수를 사용하는 코드의 구문과 구조는, 표준 동기 함수를 사용하는 것과 많이 비슷합니다. (특장점!)

 

비동기 함수를 사용하는 그 어떤 방식들보다 단순하고 직관적이다.

 


2. await

 

 

await - JavaScript | MDN

Promise 혹은 기다릴 어떤 값입니다.

developer.mozilla.org

await연산자는 Promise를 기다리기 위해 사용됩니다. 연산자는 async function 내부에서만 사용할 수 있습니다.

 

await 문은 Promise가 fulfill되거나 reject 될 때까지 async 함수의 실행을 일시 정지하고, Promise가 fulfill되면 async 함수를 일시 정지한 부분부터 실행합니다.

 

이때 await 문의 반환값은 Promise 에서 fulfill된 값이 됩니다.

 

만약 Promisereject되면, 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객체를 이용해서 비동기 함수를 처리했다.

 

이걸 asyncawait를 사용해서 바꿔보자.

 

// 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)된 프로미스가 있는 경우, 해당 결과가 반환됩니다.

 

 

Promise - JavaScript | MDN

Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.

developer.mozilla.org

 


'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