0

I'm writing a node.js function that returns a different promise depending on a condition, the cod:

if(condition){
    return promise.then(() => {
        return Promise.resolve(value)
    })
}else{
    return anotherPromise
}

Now the problem is that if the condition is true, I need to something after the promise is fulfilled, but in the other case I just return the promise, so the eslint tells me that it's a bad practice to nest promises. So this code won't work for me:

(() => {
    if(condition){
        return promise
    }
    }else{
        return anotherPromise
    }
}).then(() => {
    return Promise.resolve(value)
})

Because using this code the then callback will be executed in the two cases.

What is the best practice to handle this case?

20
  • Is switching to async/await an option? Commented Jul 2, 2018 at 11:10
  • 2
    Is the Promise.resolve(value) above really part of the code or just a placeholder for some other logic? If it's part of the code, why don't you just return value at that point? there is no need to wrap this actually. Commented Jul 2, 2018 at 11:13
  • 1
    Just write whatever js you need and compile it to whatever your target requires, you may use any javascript compiler or just the typescript one if you feel you want to use typescript. As @Sirko mentioned, async await as an option is likely the best and most comfortable solution. Commented Jul 2, 2018 at 11:18
  • 2
    babeljs.io Commented Jul 2, 2018 at 11:21
  • 1
    @AmeerTaweel babeljs.io . If you want to play a bit with presets (you need to add the ES2017 preset), go here: es6console.com . Just write your code, hit transform and check how it is transformed. Commented Jul 2, 2018 at 11:23

4 Answers 4

1

If you use classic (ES6 / ES2015+) Promise syntax you have to chain promises (nothing bad with it!).

But you have also option to split the code into functions to gain readability and avoid nesting issues:

const firstCase = () => ... // returning a promise
const secondCase = () => ... // returning a promise

if (condition) {
  return firstCase()
} else {
  return secondCase()
}

But with ES7/ES2016+ you can use async/await syntax:

// in a "async" function
async function main() {
  if (condition) {
    await promise // if you need the promise result, you can assign it
    return value // the result of an async function is always a Promise.
  } else {
    return anotherPromise
  }
}

or mix both solutions.

Sign up to request clarification or add additional context in comments.

1 Comment

Actually I guess the first solution makes the code more readable. (Since I can't use async/await)
0

A simple suggestion, (this should work) pass the condition in the resolve's argument and check it in the then block. The pseudo-code below will clarify it better:

(() => {
    if(condition){
        return new Promise((resolve,reject)=>{
            //Some tasks
            resolve(condition)

            //Some reject condition
            reject()
        })
    }
    else {
        return new Promise((resolve,reject)=>{
            //Some tasks
            resolve(condition)

            //Some reject condition
            reject()
        })
    }
}).then((condition) => {
     if(condition) {
         //Do something
     }
     else {
        //Do Nothing
     }
})

4 Comments

I am not sure what problem is your code solving. Promises are still nested.
Was focusing on this part of your question "Now the problem is that if the condition is true, I need to something after the promise is fulfilled, but in the other case I just return the promise."
Sorry, I am not able to get what do you mean by Promises are still nested.
@RajaNandSharma You haven't really changed anything in the code.
0

eslint tells me that it's a bad practice to nest promises.

Just tell it to shut *** up disable the linter on this statement. Promises have the ability to be nested precisely so that you can nest them when you need it, and this is one of those cases. Your code is fine.

3 Comments

I know this won't affect code performance, but I'm trying to use the best practices for readability and clean code.
@AmeerTaweel There's nothing wrong with nesting if control flow requires it. Promises are designed be nestable for this exact reason. If you want clean (but verbose) code, factor out the inner callback into an extra named function. If you want readable code, use async/await, but in the comments you said you can't do that.
actually I guess it's the best solution to create an extra function just for readability, I know that the code will work perfectly while nesting promises, but eslint keeps showing me that annoying warning so I was wondering what is the better way to do it.
0

Seems like you are over complicating it. The then method already returns a promise so you don’t need to put a Promise.resolve inside it.

You can for simplicity do

return condition
  ? promise.then(() => value)
  : anotherPromise

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.