1

I'm fairly new to JS development and I've recently discovered the concept of DRY (Don't Repeat Yourself), which has helped me clean up my code a lot.

I have the following type of issue in a few places throughout my project and I'm struggling to think of a way to improve it whilst maintaining the principles of readability and of not repeating code.

    if (something) {
        doPromise().then(() => {
            doSomething()
        }).catch(e => {
            doThisInstead()
        })
    } else {
        doThisInstead()
    }

The crux of it is that I need to execute doThisInstead() or whatever function / in-line code is there whenever either the if statement goes to the else block, or when the promise goes to the catch block, and in this particular instance, I have no way of knowing that the promise will go to the catch block before it is attempted.

Writing code like this can quickly become messy, so I'd appreciate any tips. Many thanks!

kougami
  • 696
  • 1
  • 6
  • 14
  • 1
    But if the promise goes to the catch that means that something is true, because otherwise you will not be entering the if and if someting is false you will go to the else. What exactly do you want to optimize? – yovchokalev Feb 08 '21 at 11:17
  • I want to avoid having doThisInstead() (or whatever is there) twice, basically, but the action I take when something is false and the promise going to the catch block is the same – kougami Feb 08 '21 at 11:29
  • It is the same, but there is no way to trigger them both, so its ok – yovchokalev Feb 08 '21 at 11:34

3 Answers3

1

You might be looking for if-else flow in promise (bluebird), just with catch instead of then:

(something
  ? doPromise().then(() => {
      doSomething()
    })
  : Promise.reject()
).catch(e => {
    doThisInstead()
})

Written with async/await, it would be

try {
    if (!something)
        throw new Error("something is wrong")
    await doPromise();
    await doSomething();
} catch(e) {
    await doThisInstead();
}

An alternative that does not rely as much on exceptions would be

if (!something || await doPromise().then(doSomething).then(() => false, () => true)) {
    doThisInstead();
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Could you please explain what's happening in the third option you posted, specifically the 2nd then? Thanks – kougami Feb 08 '21 at 16:45
  • @kougami Basically it's what Terry did below with `errorOccurred`, just using promise style. You might want to have a look at [how `.then(…, …)` works](https://stackoverflow.com/q/24662289/1048572). – Bergi Feb 08 '21 at 17:20
0

If you use the _async / await _ syntax, you can await doPromise(), then run doThisInstead() if either something is falsey or an error occurred, this means only one call to doThisInstead() in your code.

This example will cause doPromise() to fail 50% of the time.

let something = true;

// Fail 50% of the time
function doPromise() {
    return new Promise((resolve, reject) => setTimeout(Math.random() <= 0.5 ? resolve: () => reject(new Error("Some error")), 100));
}

function doSomething() {
    console.log("doSomething()");
}

function doThisInstead() {
    console.log("doThisInstead()");
}

async function test() {
    errorOccurred = false;
    if (something) {
        try {
            await doPromise();
            doSomething();
        } catch (e) {
            errorOccurred = true;
        }
        console.log("doPromise: " + (errorOccurred ? "error occurred." : "ran successfully"));
    }
    
    // Run doThisInstead() if either an error occurred or something is falsey
    if (!something || errorOccurred) {
        doThisInstead();
    }
}

test()
Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
0

This can be solved with a Promise, using the following code:

function hypotheticalFunction() {
    const doSomething = () => {
        // stuff
    }
    const doThisInstead = () => {
        // stuff
    }
    const doSomethingHandler = () => {
        return new Promise((resolve,reject) => { 
            if (something) {
                doPromise().then(() => {
                    doSomething();
                    resolve();
                }).catch(() => {
                    reject();
                })
            } else {
                reject();
            }
        })
    }
    doSomethingHandler().catch(doThisInstead);
}
hypotheticalFunction();
kougami
  • 696
  • 1
  • 6
  • 14