Olivier
Olivier

Reputation: 3471

How can I handle conditional callbacks in javascript while keeping it DRY?

I have been playing with NodeJS lately and i found myself stuck with a regular pattern issue :

I have a main operation running on, depending on some config parameters, i need to perform an extra step, but this step is async :

    if(request.config.save) {

        fs.writeFile(request.config.save, decryptedData, function(err) {
            // Continue the operation with a callback...
            // Perform some other ops.
            if(typeof callback == 'function') callback(decryptedData);
        }.bind(this));

    } else {

        // Continue the same operation without a callback
        // Perform some other ops.
        if(typeof callback == 'function') callback(decryptedData);

As you can see this code is not DRY as the main ending (callback) is called twice.

Only way I see is to use functions (but once again the function call is not DRY... And code could be really bloated this way...

So is there a pretty ninja trick to solve this?

Upvotes: 4

Views: 2854

Answers (2)

davin
davin

Reputation: 45525

function cb() {
   if (typeof arguments[0] === 'function')
      arguments[0].apply(null, Array.prototype.slice.call(arguments,1));
}

Shouldn't be more than around 10 characters longer (might have to bind) than a normal function call without the typeof check, and assuming no bind it shouldn't be more than 4.

There is no way to solve this without paying some price, somewhere.

Upvotes: 0

Matt
Matt

Reputation: 41832

Well, a single line of code isn't all that repetitive, but if you're doing more than that it can get very non-dry. What about just wrapping your final logic into a function, and calling that inside your conditionals?

var endTick = function(){
    if(typeof callback == 'function') callback(decryptedData);
}

if(request.config.save) {

    fs.writeFile(request.config.save, decryptedData, function(err) {
        // Continue the operation with a callback...
        // Perform some other ops.
        endTick();
    }.bind(this));

} else {

    // Continue the same operation without a callback
    // Perform some other ops.
    endTick();
}

Upvotes: 4

Related Questions