Async function with callback

Viewed 115

I'm working on code that contains async functions with callbacks, i.e.

async getData(options, callback) {

I really can't think of a reason why anyone would use callbacks in an async function. So I'm thinking about rewriting it to return the Promise without a callback.

I'm asking this question just to be sure. Is there a valid reason to write code like this (that I don't get). I don't want to offend my coworker, but at the same time, I don't like seeing overcomplicated code that checks for whether callback is not undefined and returns the callback (and at some spots even does different logic based on that).

1 Answers

It depends on what the callback is for.

If it's just to report the asynchronous completion of the function's work, then there's no reason for it — async functions do that with the promise they return.

But if it's for a different reason, it can be valid. For instance, an async function that copies data from point A to point B might accept an optional callback that transforms a record of that data in some way: The async function reads a record from point A, passes it through the callback, and rites the result to point B; the promise the function returns is for the entire operation. (Not the best example in the world, you might write that as a pair of async generators instead, but...)

I had reason recently to write this odd-looking duck:

function nextFrame(cb) {
    return new Promise(resolve => {
        requestAnimationFrame(() => {
            cb();
            resolve();
        });
    });
}

...so that I could do this in an async function:

await nextFrame(() => {/*...updates for frame here...*/});

I can't just make it

await nextFrame();
// ...updates for frame here...

for a couple of reasons (because the processing model means my subsequent code wouldn't be run before the frame, and because I wouldn't want all of the work following it in my async function until the next await to be just prior to the frame being drawn).


Additionally, @VLAZ makes a very good point in their comment, if an API previously supported callbacks for completion where the function didn't previously return anything, it can be retrofitted to return a promise but still accept a callback. One of the MongoDB client libs did that IIRC.

Related