async와 await를 수동으로 구현해보세요

async와 await는 Promise 코드에서의 중복을 해결하는 문법입니다. 그러나 async 함수의 반환 값은 항상 Promise이며, 이는 async/await의 장점이지만 과도한 사용에는 주의해야 합니다. async 함수가 기다리게 하는 기능은 제너레이터 함수를 기반으로 합니다.

async와 await는 주로 API 요청을 처리하는데 사용됩니다. 아래는 간단한 백엔드 서버 코드입니다.


const http = require('http');
http.createServer((req, res) => {
    res.setHeader('Access-Control-Allow-Origin', '*');
    if (req.url === '/res1') {
        res.end(JSON.stringify({
            name: 'jack',
            age: 18
        }));
    } else if (req.url === '/res2?name=jack') {
        res.end('jackInfo');
    } else if (req.url === '/res3?msg=jackInfo') {
        res.end('aaaaa');
    }
}).listen(9999);

주요 코드는 아래와 같습니다.


function* asd(generator) {
    let iterator = generator();

    function handler(result) {
        if (result.done) {
            return;
        }
        if (result.value instanceof Promise) {
            result.value.then(value => {
                handler(iterator.next(value));
            });
        }
    }

    handler(iterator.next());
}

let iterator = asd(function* () {
    let res1 = yield axios.get('http://localhost:9999/res1');
    console.log(res1);
    let res2 = yield axios.get('http://localhost:9999/res2?name=' + res1.name);
    console.log(res2);
    let res3 = yield axios.get('http://localhost:9999/res3?msg=' + res2.data);
    console.log(res3);
});
iterator.next();

제너레이터 함수에 대한 자세한 내용은 아래 링크를 참조하세요.


function* gen() {
    console.log(111);
    let one = yield 'hello';
    console.log(one);
    yield 'world';
}
let iterator = gen();
console.log(iterator.next());
iterator.next('aaa');

제너레이터 함수의 동작 방식은 다음과 같습니다:

  • 첫 번째 next 호출 시, 제너레이터 함수 내부의 첫 번째 yield까지 실행됩니다.
  • 두 번째 next 호출 시, 첫 번째 yield의 값을 전달받아서 그 다음 yield까지 실행됩니다.
  • yield 뒤의 표현式은 값이 아닌 제너레이터 객체의 현재 상태를 나타냅니다.
  • yield 뒤에 전달된 값은 제너레이터 함수 내부에서 해당 yield의 반환값이 됩니다.

상세 내용은 여기를 참조하세요.

태그: JavaScript async await generator Promise

9월 29일 08:55에 게시됨