【发布时间】: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