Conditional promises in Ember.RSVP

538 Views Asked by At

I have a simple if else scenario where I need to do something if a variable is set otherwise just perform in the else part:

if(flag) {
  doSomething();
}
doNextThing(someParam);

If flag is set, then I must doSomething() and doNextThing()

Both doSomething and doNextThing return promises. What is the best way to implement this?

Currently my code looks like:

if(flag) {
  doSomething().then(doNextThing);
} 
else doNextThing(someParam);

What is the best way to elegantly combine the two in cleaner code segment?

I tried:

var somePromise = new Promise(function(resolve, reject){
     if(flag)
        doSomething.then(resolve(result));
      else resolve();
})

return somePromise.then(doNextThing(resolvedValue))

but this doesn't work. Seems like the promise doSomething is never resolve and the code returns immediately. I also tried several variations of the above including:

var somePromise = new Promise(function(resolve, reject){
     if(flag)
        doSomething.then(resolve);
      else resolve();
})

and:

var somePromise = new Promise(function(resolve, reject){
     if(flag)
        doSomething.then(function(result){
             resolve(result);
        }.bind(this));
      else resolve();
}.bind(this));

but nothing works, except for the very first option. So, my question is - Is there a better/elegant way to achieve this?

3

There are 3 best solutions below

0
Daniel On

Try moving to Ember.RSVP.Promise and returning promise in your function (it should chain them):

var somePromise = new Ember.RSVP.Promise(function (resolve, reject) {
     if (flag) {
         return doSomething;
     }
     resolve();
});

return somePromise.then(doNextThing);
0
Tiago Engel On

One elegant way of doing this:

var firstThing = flag ? doSomething() : Ember.RSVP.resolve();
firstThing.then(doNextThing.bind(null, someParam));

If you look in the then function I am using the bind function to create a partially applied function.

This is because the function then expects a function as his argument, so you can't call it like this firstThing.then(doNextThing(param)). This way you are passing the result of the function, not the function.

0
Scott Nedderman On

How about something like this:

Em.RSVP.allSettled([
    !flag || doSomething(),
    doNextThing()
])

It will try each item in the array, but skipping the first if the flag is false. If you want it to skip doNextThing() if doSomething() fails, then use Em.RSVP.all().