Search code examples
javascriptecmascript-6async-awaitgenerator

Which one of my function declaration is better? generator or async/await?


I wanna write a function but I don't know which one of them is better:

function* call() {
    try {
        const a = yield api(1);
        const b = yield api(2);
        const c = yield api(3);
        const d = yield api(4);

        return [a, b, c, d];
    } catch (e) {
        console.log(e);
    }
}

or Async/Await:

async function call() {
    try {
        const a = await api(1);
        const b = await api(2);
        const c = await api(3);
        const d = await api(4);

        return [a, b, c, d];
    } catch (e) {
        console.log(e);
    }
}

Both of them works well, I don't know which one of them is better or what is the difference between them.


Solution

  • No they are not exactly the same, the differences are as follows:

    1. The call() invocation with return you an iterator object for the generator function* whereas the async function will return you an array wrapped in a promise.

    2. If you don't pass any value to the iterator.next() calls after getting it from the generator invocation, the resulting array you are returning from the generator function will have four undefined values. But in the async version you will get back the values returned from the api() calls in the Promise wrapped array.

    3. Also the yield statements would return you the values when you iterate through the iterator, but in the async function the await will wait for the Promise returned by api() calls to be resolved then move on the next await else if the value is not a Promise from the api() call it will convert it to resolved Promise and the value of the await expression will become the value of the resolved Promise.

    These three points can be illustrated below by a snippet.

    1. Generator function:

    function* call() {
        try {
            const a = yield 1;
            const b = yield 2;
            const c = yield 3;
            const d = yield 4;
    
            return [a, b, c, d];
        } catch (e) {
            console.log(e);
        }
    }
    const itr = call();
    //next() is not invoked with any params so the variables a, b, c, d will be undefiend
    console.log(itr.next().value); 
    console.log(itr.next().value);
    console.log(itr.next().value);
    console.log(itr.next().value);
    console.log(itr.next().value); 

    1. Async function:

    async function call() {
        try {
            const a = await 1;
            const b = await 2;
            const c = await 3;
            const d = await 4;
    
            return [a, b, c, d];
        } catch (e) {
            console.log(e);
        }
    }
    //call() will return a Promise
    call().then(data => console.log(data));