JS Promises - if-else flow when only single path i

2020-04-30 16:21发布

问题:

I'm rewriting some legacy code, which was build using sync ajax (so so bad). Now I'm using Promises (specifically Bluebird). There are a lot of situations, where function has a lot of paths, from which only one is async.

The problem is that I have to identify all paths and manually return new promise from each of them. Like this:

function syncFn() {
    // sync code return
}
function asyncFn() {
    // some async code here that return Promise
}
function myMegaFunction() {
    if ( ... ) {
        return Promise.resolve(syncFn());
    }
    else if ( ... ) {
        if ( ... ) {
            return Promise.resolve(syncFn());
        }
        else if ( ... ) {
            return Promise.resolve(syncFn());
        }
        else {
            return asyncFn(); // only async function here
        }
    }
    else {
        return Promise.resolve();
    }
}

Is there some way or pattern, that could simplify this? Maybe something like - if return undefined, then wrap as empty promise?

回答1:

You can use the Promise.method helper for this:

var myMegaFunction = Promise.method(function myMegaFunction() {
    // return values
    // throw errors
    // return promises
});

…and myMegaFunction(…) will always return a promise. It automatically catches exceptions, and wraps the result of your function in a Promise.resolve(…).



回答2:

Simpler

function myMegaFunction() {
    if ( ... ) {
        syncFn();
    }
    else if ( ... ) {
        if ( ... ) {
            syncFn();
        }
        else if ( ... ) {
            syncFn();
        }
        else {
            return asyncFn(); // only async function here
        }
    }
    return Promise.resolve();
}

Not by much ... but simpler

As you are returning asyncFn in the one place it needs to be done, you can simply put a return Promise.resolve() ... actually ... let me edit that, I just noticed something ...

function myMegaFunction() {
    if ( ... ) { //A
        ;
    }
    else if ( ... ) { //B
        if ( ... ) { //C
            ;
        }
        else if ( ... ) { // D
            ;
        }
        else {
            return asyncFn(); // only async function here
        }
    }
    synchFn();
    return Promise.resolve();
}

could be written as

function myMegaFunction() {
    if(!A && B && !C && !D) {
        return asyncFn();
    }
    synchFn();
    return Promise.resolve();
}

edit:: not quite - but close - that synchFn is a bitch

function myMegaFunction() {
    if(!A && B && !C && !D) {
        return asyncFn();
    }
    if(A || B) {
        synchFn();
    }
    return Promise.resolve();
}