Based on the question here: jQuery chaining and cascading then's and when's and the accepted answer, I want to break the promise chain at a point but haven't yet found the correct way. There are multiple posts about this, but I am still lost.
Taking the example code from the original question:
Menus.getCantinas().then(function(cantinas){ // `then` is how we chain promises Menus.cantinas = cantinas; // if we need to aggregate more than one promise, we `$.when` return $.when(Menus.getMeals(cantinas), Menus.getSides(cantinas)); }).then(function(meals, sides){ // in jQuery `then` can take multiple arguments Menus.sides = sides; // we can fill closure arguments here Menus.meals = meals; return Menus.getAdditives(meals, sides); // again we chain }).then(function(additives){ Menus.additives = additives; return Menus; // we can also return non promises and chain on them if we want }).done(function(){ // done terminates a chain generally. // edit HTML here });
How would I break the chain if cantinas.length == 0
? I would not want to get the meals, neither the additives, frankly I would want to call some kind of "empty result" callback. I have tried the following which is very ugly (but works...). Teach me the correct way. This still is a valid result, so not a "fail" per se, just empty result I would say.
var emptyResult = false; Menus.getCantinas().then(function(cantinas){ Menus.cantinas = cantinas; if (cantinas.length == 0) { emptyResult = true; return "emptyResult"; //unuglify me } return $.when(Menus.getMeals(cantinas), Menus.getSides(cantinas)); }).then(function(meals, sides){ if (meals == "emptyResult") return meals; //look at my ugliness... Menus.sides = sides; Menus.meals = meals; return Menus.getAdditives(meals, sides); }).then(function(additives){ if (additives == "emptyResult") return additives; Menus.additives = additives; return Menus; }).done(function(){ if (emptyResult) //do empty result stuff else // normal stuff });
In order to break a promise honorably, you need to be sure to do the following: Acknowledge that you are breaking a promise. This isn't something you can mask or hide. Don't wait too long to communicate about this either.
Return valuereturns a value, the promise returned by then gets resolved with the returned value as its value. doesn't return anything, the promise returned by then gets resolved with an undefined value. throws an error, the promise returned by then gets rejected with the thrown error as its value.
Sounds like you want to branch, not to break - you want to continue as usual to the done
. A nice property of promises is that they don't only chain, but also can be nested and unnested without restrictions. In your case, you can just put the part of the chain that you want to "break" away inside your if
-statement:
Menus.getCantinas().then(function(cantinas) { Menus.cantinas = cantinas; if (cantinas.length == 0) return Menus; // break! // else return $.when(Menus.getMeals(cantinas), Menus.getSides(cantinas)) .then(function(meals, sides) { Menus.sides = sides; Menus.meals = meals; return Menus.getAdditives(meals, sides); }).then(function(additives) { Menus.additives = additives; return Menus; }); }).done(function(Menus) { // with no cantinas, or with everything });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With