我刚刚写道:
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之后,等待“然后”将运行并删除我的数据库中的东西。但是如果我通过输入愚蠢的值然后输入一个合理的值来绕圈,那么等待的“那么”将不会运行,也不会是拒绝处理程序。
我有点怀疑问题是我履行的承诺与我的处理程序附带的承诺不同,但我仍然不明白为什么它以某种方式工作而不是另一种方式。
我猜你需要剩下的代码才能重现这个,所以它在http://quorve.com/rsvpissue/babylog.html。这是前面提到的等待“然后”:
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,之后,你会看到一个新的过渡,右下角代表饮酒会话的结束,数量为150ml。当您按取消时,您正在使用第一个递归调用。
重新加载页面(重置数据库。)像以前一样点击瓶子,但将滑块推到顶部(没有婴儿可以喝那么多),然后按OK。关闭唠叨框并再次出现对话框。如果你愿意,重复一遍将滑块推到较低的值,然后按OK。现在你看到了问题:对话框消失了,所以我们退出了递归,但是按钮和DB没有更新,因为没有调用继续,也没有被拒绝的情况。
这是RSVP中的错误还是我误解了承诺?
TIA,Adrian。
答案 0 :(得分:2)
怀疑它!我应该说:
fulfill(getQtyFor(state,down))
而不是
return getQtyFor(state,down)
用于递归调用。