【问题标题】:Two recursive calls in promise failingPromise 中的两个递归调用失败
【发布时间】:2014-01-06 12:38:22
【问题描述】:

我刚刚写了:

function getQtyFor(state,down) {
  var promise = new RSVP.Promise( function (fulfill, reject) {
      if (!down && (state=='bottle' || state=='pumped')) {
        doDialog('volume')
          .then ( validateVolume ,
                  function ()    { hideDialog('volume');
                                   return getQtyFor(state,down);     } )
          .then ( function (q)   { hideDialog('volume'); 
                                   fulfill(q); },           
                  function (e)   { hideDialog('volume');
                                   alert("Bad input "+e); 
                                   return getQtyFor(state,down);       } )
      } else fulfill(0);
  });
  return promise; 
}

您可以在其中看到两个递归调用。我发现第一个按预期工作,第二个按预期循环,但在使用第二个后我从未得到“满足”。换句话说,我可以通过取消对话(第一次递归)或输入验证器不喜欢的值(第二次递归)来循环运行。在前一种情况下,在我最终决定点击 OK 后,等待“then” 将运行并将内容放入我的数据库中。但是如果我通过输入愚蠢的值来循环,然后最终输入一个合理的值,那么等待的“then”将不会运行,它也不会是拒绝处理程序。

我有点怀疑问题是我履行的承诺与附加了我的处理程序的承诺不同,但我仍然不明白为什么它以一种方式而不是另一种方式工作。

我猜你需要其余的代码来重现它,所以它位于http://quorve.com/rsvpissue/babylog.html。这是前面提到的等待“then”:

function stick(down) {
  return function(ob) {
    return getQtyFor(ob.attr('id'), down)
    .then( getStickyFields(down, ob), alert ) //NEITHER REACHED AFTER FAILED VALIDATE
    .then( db_insert('transitions') )                         
    .then( function() { updateButtonAppearance(down)(ob); } , alert);
  }
}

以及从有问题的递归函数中调用的东西:

function doDialog(log) {
  var promise = new RSVP.Promise( function(fulfill, reject) {
    $('#'+log).dialog({
      dialogClass: "no-close",
      modal: true,
      buttons: {
        "OK":     function() { fulfill($(this)); },
        "Cancel": function() { reject(); }
      }
    });
  });
  return promise;
}

function validateVolume(form) {
  vol = form.find("[name=qty]").val();
  if ( vol > 200 ) { 
    throw("vol"); }
  return vol;
}

重现步骤:

使用 Chrome,因为它使用 WebSQL。 (我知道它已经过时了,但我们不要转移话题。)

转到http://quorve.com/rsvpissue/babylog.html

点击 Zach 的瓶子(按下的按钮)并在对话框中点击取消。该对话框一直存在,直到您点击 OK,之后,您会在右下角看到一个新的过渡,表示饮用量为 150 毫升的饮酒会话结束。当您按下取消时,您正在使用第一个递归调用。

重新加载页面(重置数据库)。像以前一样单击瓶子,但将滑块推到顶部(没有婴儿可以喝那么多),然后按确定。关闭 nag 框,对话框重新出现。如果你喜欢,请重复。将滑块推到较低的值,然后按 OK。现在你看到了问题:对话框消失了,所以我们退出了递归,但是按钮和数据库没有更新,因为没有调用延续,也没有被拒绝的情况。

这是 RSVP 中的错误还是我误解了承诺?

TIA,阿德里安。

【问题讨论】:

    标签: javascript recursion promise


    【解决方案1】:

    猜对了!我应该说:

    fulfill(getQtyFor(state,down))
    

    而不是

    return getQtyFor(state,down)
    

    用于递归调用。

    【讨论】:

      猜你喜欢
      • 2018-09-07
      • 2021-02-03
      • 1970-01-01
      • 1970-01-01
      • 2021-04-29
      • 1970-01-01
      • 2016-05-26
      • 2012-10-06
      • 1970-01-01
      相关资源
      最近更新 更多