moztemur
moztemur

Reputation: 981

How to call asynchronous function conditionally in JavaScript

I would like to make a conditional asynchronous function call in JavaScript/ES5.

Say I have a module myService with a function myAsyncFunction, which is doing some logic inside and returns result with a callback like the following:

myService.myAsyncFunction(param1, param2, (error, success) => {
    if (error) {
        // handle error
        return;
    }
    // handle success
});

But in certain conditions, I would like it to directly fall into the "handle success" without running the logic inside myService.myAsyncFunction, which may take some time and resources.

The most straightforward way that I imagine is to create a dummy function which imitates myService.myAsyncFunction and calls the callback with no error like the following:

var myGenericFunction;

if ( /* I would like to skip unnecessary logic */) {
    myGenericFunction = function (param1, param2, callback) {
        callback(null);
    }
} else {
    myGenericFunction = myService.myAsyncFunction;
}

myGenericFunction(param1, param2, (error, success) => {
    if (error) {
        // handle error
        return;
    }
    // handle success
});

This is what I have ended up with but I guess there should be a better way in terms of both syntax and performance. Do you have any suggestion for it?

Note: Promise.resolve on ES6 can propose a solution to directly fall into success case but I wonder what would be ES5 solution.

Upvotes: 0

Views: 2413

Answers (2)

mattezell
mattezell

Reputation: 617

I can think of a couple of alternate approaches to rolling your own Promise implementation.

You can use an existing one, such as Bluebird - http://bluebirdjs.com/docs/getting-started.html

You can also use a transpiler, such as Babel, which would allow you to write all of the next-gen ES that you wish and have it converted to ES5 pre-runtime - https://babeljs.io/docs/en

Upvotes: 0

Evert
Evert

Reputation: 99523

First, it's super easy to pull in a Promise polyfill for javascript environments that don't support it. It should work all the way back to Ecmascript 3.

Ignoring that, if you have an async function such as this:

function myAsync(arg1, callback) {

}

But for some value or arg1 you want to immediately call the callback, but you can't change the function, the reasonable way to do this, is indeed to just wrap it:

function myAsyncWrapped(arg1, callback) {
   if (arg1 === SOME_VALUES) {
     callback(null, true);
   } else {
     myAsync(arg1, callback);
   }
}

If you need to do this for many async functions, it could be generalized as:

function asyncWrapper(innerFunction) {
   return (arg1, callback) {
     if (arg1 === SOME_VALUES) {
       callback(null, true);
     } else {
       innerFunction(arg1, callback);
     }
   }
}

so you can call this as:

myAsyncWrapped = asyncWrapper(myAsync);

Upvotes: 2

Related Questions