Is it OK to pass an async function to setImmediate in order to call an arbitrary function asynchronously?

Viewed 353

I want to call a given function asynchronously. The wrapper function tryCallAsync is one way of doing this. This approach works. However, it requires that the callback for setImmediate to be an async function. This seems wrong, as the callback is returning a Promise that is not used. Is it wrong to pass an async function to setImmediate for this purpose?

async function tryCallAsync(fn, ...args) {

    return new Promise((r, j) => {

        setImmediate(async () => {

            try {
                r(await fn(...args));
            }
            catch (e) {
                j(e);
            }
        })
    })
}

//  Using tryCallAsync

let resolveAsync = tryCallAsync(()=>{
    return new Promise((r,j)=>{
        setImmediate(()=>r('resolveAsync'));
    });
})

resolveAsync.then((resolve)=>console.log(resolve));

let resolve = tryCallAsync(()=>{
    return 'resolve';
});

resolve.then((resolve)=>console.log(resolve));

NB: https://www.youtube.com/watch?v=e3Nh350b6S4

2 Answers

Yes, it's wrong, for multiple reasons:

  • setImmediate doesn't handle the returned promise, especially it doesn't deal with errors1
  • Don't put business logic in asynchronous (non-promise) callbacks when using promises. Settle a promise from there, nothing else.

1: And even while your particular callback never rejects the returned promise due to the try/catch, it still feels wrong

Your function should be written as

async function tryCallAsync(fn, ...args) {
    await new Promise(resolve => {
        setImmediate(resolve);
    });
    return fn(...args);
}

This approach doesn't waste a Promise, however, still, it's not as performant as the conventional way of doing this.

function tryCallAsync(fn, ...args) {

    return new Promise((r, j) => {

        setImmediate(() => {

            (async function () {

                return await fn(...args);

            })().then(r).catch(j);
        });
    });
}
Related