Search code examples
javascriptasync-awaites6-promise

ERR_UNHANDLED_REJECTION UnhandledPromiseRejection when awaited inside an array of promise Objects


I am trying to understand async await with promises and for..of loop. I have a function which generates promise by resolving if an even number is passed to it and by rejecting if odd number is passed to it. Inside an async function I am tying to await but getting UnhandledPromiseRejection even though I am catching the error. My question is what points i am missing. Why I am getting UnhandledPromiseRejection and how to handle it. I need conceptual information

function genPromise(value) {
    return new Promise((resolve, reject) => {
        if (value % 2) {
            resolve(`The value ${value} is odd`);
        } else {
            reject(`The value ${value} is even`);
        }
    })
}

(async function () {

    x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    let y = x.map(d => genPromise(d))
    try {
        for await (let k of y) {
            console.log(k);
        }
    } catch (err) {
        console.log(err)
    }
})();

Solution

  • for await( is only intended for use with async iterables. You do not have an async iterable - only a normal iterable, in which case it's equivalent to for..of:

    for (const k of y) {
      console.log(k);
    }
    

    The k promise is not being caught, hence the rejection.

    Await k inside the loop, without for await:

    function genPromise(value) {
        return new Promise((resolve, reject) => {
            if (value % 2) {
                resolve(`The value ${value} is odd`);
            } else {
                reject(`The value ${value} is even`);
            }
        })
    }
    
    (async function () {
    
        x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let y = x.map(d => genPromise(d))
        try {
            for (const k of y) {
                console.log(await k);
            }
        } catch (err) {
            console.log('error', err)
        }
    })();

    If you wanted to make an async iterable from the array of numbers, then you'd do something like:

    function* genPromise(arr) {
        for (const value of arr) {
            yield new Promise((resolve, reject) => {
                if (value % 2) {
                    resolve(`The value ${value} is odd`);
                } else {
                    reject(`The value ${value} is even`);
                }
            });
        }
    }
    
    (async function () {
        const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        try {
            for await (const k of genPromise(arr)) {
                console.log(k);
            }
        } catch (err) {
            console.log('error', err)
        }
    })();