我正在[{3}}的[分叉],添加支持以允许事件处理程序返回jWizard。
以下代码按预期工作:
stephidden
事件。(针对此问题进行了简化; Promise
objects)
/** Invokes the `stephide` event for the current element and hides
* it if the event handler doesn't prevent it.
*
* @param $el {jQuery} Element that will be hidden.
*/
_leave: function ($el) {
var event = $.Event("stephide"),
dfd = $.Deferred(),
effect = { effect: "blind", direction: "left", duration: 250 };
$el.trigger(event);
if(event.isDefaultPrevented()) {
dfd.reject();
} else {
$el.hide(effect, function() {
$el.trigger("stephidden");
dfd.resolve();
});
}
return dfd.promise();
}
但是,当我修改代码以期望Promise
时,传递给$el.hide()
的回调不会触发。元素会隐藏,但回调不会被调用。
_leave: function ($el) {
var event = $.Event("stephide"),
dfd = $.Deferred(),
effect = { effect: "blind", direction: "left", duration: 250 };
$el.trigger(event);
// event.returnValue is a Promise object; see below.
$.when(event.returnValue).then(
function() {
// $el.hide DOES run...
$el.hide(effect, function() {
// ... but this code never does!
console.log("stephidden");
$el.trigger("stephidden");
dfd.resolve();
});
},
dfd.reject
);
return dfd.promise();
}
/** Event handler for the stephide event.
*/
$("...").on("stephide", function(event) {
var dfd = $.Deferred();
// ...
event.returnValue = dfd.promise();
});
我做错了什么?
答案 0 :(得分:0)
我看到以下可能的问题:
如果hide.returnValue
是一个承诺而且当你认为它没有得到解决时,则可能会导致问题(我们看不到该代码)。
如果某些内容中断了隐藏动画(例如动画完成前的.hide()
),则不会调用.stop()
的回调。您可以使用.promise()
而不是回调来解决中断的问题,因为即使动画停止也会一直解决。
如果在动画完成之前从DOM中删除了对象(使用类似jQuery .remove()
或.empty()
或.html()
的父级,那么它将不会调用这是回调。
如果你要返回一个承诺,它通常也是一个更简单的界面,总是返回一个承诺(在hide.returnValue
中)。如果没有什么可以等待,那么只需返回已经解决的承诺。这使得调用代码变得更加简单,因为他们可以假设那里有一个承诺并编写一组代码。你觉得它听起来有时只是一个承诺,这是一个很难编码的。
我建议简化你的承诺代码,你可以使用现有的承诺。
我认为你可以用这个简化的代码做你想做的一切:
_leave: function ($el) {
var event = $.Event("stephide"),
effect = { effect: "blind", direction: "left", duration: 250 };
$el.trigger(event);
return $.when(event.returnValue).then(function() {
return $el.hide(effect).promise().then(function() {
console.log('stephidden');
$el.trigger("stephidden");
});
});
}
如果hide.returnValue
始终是承诺,则您不需要$.when()
,因为您可以直接在承诺上致电.then()
。围绕它使用$.when()
即使.then()
不是承诺,hide.returnValue
也会执行。
这也使用内置的.promise()
函数来隐藏动画而不是回调,以提高其可靠性和使用promises的一致性。
如果event.returnValue
始终是承诺对象,则可以使用此缩短版本:
_leave: function ($el) {
var event = $.Event("stephide"),
effect = { effect: "blind", direction: "left", duration: 250 };
$el.trigger(event);
return event.returnValue.then(function() {
return $el.hide(effect).promise().then(function() {
console.log('stephidden');
$el.trigger("stephidden");
});
});
}