如何正确地打破承诺链?

如何正确地打破承诺链?

基于以下问题:然后是jQuery链接和级联,然后是而被接受的答案,我想打破承诺链在某一点,但还没有找到正确的方式。确实有倍数 员额 关于但我还是迷路了。

以原始问题中的示例代码为例:

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});

我怎么打破锁链cantinas.length == 0?我不想得到食物,也不想得到添加物,坦率地说,我想称之为某种“空洞的结果”回调。我试过以下几种方法很丑(但有效.)教我正确的方法。这仍然是一个有效的结果,所以不是“失败”本身,只是空洞的结果,我想说。

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});


茅侃侃
浏览 482回答 3
3回答

蓝山帝景

首先,我认为最好是说你是在“绕开”承诺链,而不是“打破”它。正如您所说,在一些地方对“emptyResult”进行测试是非常糟糕的。幸运的是,在遵循相同的不执行部分承诺链的一般原则的同时,还提供了一种更优雅的机制。另一种机制是使用承诺拒绝来控制流程,然后在链的后面重新检测特定的错误条件,并将其重新放到成功的路径上。Menus.getCantinas().then(function(cantinas) {     Menus.cantinas = cantinas;     if(cantinas.length == 0) {         return $.Deferred().reject(errMessages.noCantinas);     } 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;}).then(null, function(err) {     //This "catch" exists solely to detect the noCantinas condition      //and put the chain back on the success path.     //Any genuine error will be propagated as such.     //Note: you will probably want a bit of safety here as err may not be passed and may not be a string.     return (err == errMessages.noCantinas) ? $.when(Menus) : err;}).done(function(Menus) {     // with no cantinas, or with everything});var errMessages = {     'noCantinas': 'no cantinas'};从好的方面来说,我发现缺乏嵌套有助于更好地阅读自然成功的道路。而且,至少对我来说,如果需要的话,这种模式需要最少的精神杂耍来适应更多的旁路。另一方面,这种模式的效率略低于Bergi。cantinas.length == 0路径需要多一个(如果多个旁路被编码,则每个旁路需要一个)。此外,此模式还需要可靠地重新检测特定错误条件,因此errMessages对象-有些人可能会找到贬低。

慕田峪7331174

听起来像你想支部, 不折断-你想继续和往常一样done..承诺的一个优点是,它们不仅是连锁的,而且可以是嵌套和非嵌套没有限制。在你的例子中,你可以把你想要“挣脱”的链条的一部分放在你的if-声明: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});

萧十郎

对于使用内置浏览器承诺的人来说,他们需要寻找一种方法来停止承诺链,而不让所有消费者都知道拒绝案例,从而触发任何链接。then或catch或者扔东西Uncaught (in promise)错误,您可以使用以下方法:var noopPromise = {   then: () => noopPromise,    catch: () => noopPromise}function haltPromiseChain(promise) {   promise.catch(noop)   return noopPromise}// Use it thus:var p = Promise.reject("some error")p = haltPromiseChain(p)p.catch(e => console.log(e))    // this never happens从根本上说,nooppro而论是一个基本的存根承诺接口,它使用链接函数,但从不执行任何函数。这依赖于这样一个事实,即浏览器显然使用鸭子类型来确定某件事情是否是一种承诺,所以YMMV(我在Chrome 57.0.2987.98中测试了这一点),但如果这成为一个问题,您可能会创建一个实际的承诺实例,并对其当时和捕获方法进行中性处理。
打开App,查看更多内容
随时随地看视频慕课网APP