在插件中使用 jquery 延迟承诺
Using jquery deferred promises inside plugins
我写了一个插件,它应该从 API 中获取错误消息并将它们显示在元素的 HTML 中。我想将它实现为一个承诺,以便其他事件可以通过 done
或 always
回调链接到它。插件的简化版本如下所示:
(function( $ ) {
$.fn.flashAlerts = function() {
var deferred = $.Deferred();
var field = $(this);
$.getJSON( "alerts", {})
.done(function( data ) {
// Display alerts
field.html(data['message']);
deferred.resolve();
});
return deferred.promise();
};
}( jQuery ));
使用场景可能如下所示:
$("#myForm").submit(function(e) {
e.preventDefault();
var form = $(this);
// Disable submit button
form.disableSubmitButton();
var serializedData = form.serialize();
var url = form.attr('action');
$.ajax({
type: "POST",
url: url,
data: serializedData
}).fail(function(jqXHR) {
// Display errors on failure
$('#alerts').flashAlerts().done(function() {
// Re-enable submit button
form.enableSubmitButton();
});
});
});
想法是执行以下操作序列:
- POST表格。在请求之前,禁用提交按钮。请求完成后,
- 获取
alerts
api 中的错误。 that 请求完成后,显示错误消息。显示错误消息后,
- 重新启用提交按钮。
这段代码似乎可以正常工作,但我不知道延期是否按正确的顺序工作(或者我是否只是对请求的时间感到幸运)。
所以,我这样做正确吗?我如何测试延期订单是否符合要求?
This code seems to work as it stands, but I have no idea if the deferrals are working in the correct order
是的,它们确实按预期工作。
So, am I doing this correctly?
不,您在 flashAlerts
方法中使用了 deferred antipattern。此外,您忽略从 ajax 请求到 /alerts
的错误,因此如果两个请求都失败,则不会重新启用该按钮。不确定这是否是您的意图,但我会在最后一次回调中使用 .always
而不是 .done
。
以下是我要写的内容:
$.fn.flashAlerts = function() {
var field = $(this);
return $.getJSON( "alerts", {})
.then(function(data) {
// Display alerts
field.html(data['message']);
return data;
});
};
How could I test that the deferral order is as desired?
没什么可测试的。通过您的代码布局方式,完全不可能在 $('#alerts').flashAlerts()
之前调用 form.enableSubmitButton();
或在 $.ajax({ … })
之前调用 $.getJSON( "alerts", {})
。当然,你必须相信那些在完成之前没有解决承诺的函数(这是你的代码工作所必需的),但执行顺序是无法逾越的。
我写了一个插件,它应该从 API 中获取错误消息并将它们显示在元素的 HTML 中。我想将它实现为一个承诺,以便其他事件可以通过 done
或 always
回调链接到它。插件的简化版本如下所示:
(function( $ ) {
$.fn.flashAlerts = function() {
var deferred = $.Deferred();
var field = $(this);
$.getJSON( "alerts", {})
.done(function( data ) {
// Display alerts
field.html(data['message']);
deferred.resolve();
});
return deferred.promise();
};
}( jQuery ));
使用场景可能如下所示:
$("#myForm").submit(function(e) {
e.preventDefault();
var form = $(this);
// Disable submit button
form.disableSubmitButton();
var serializedData = form.serialize();
var url = form.attr('action');
$.ajax({
type: "POST",
url: url,
data: serializedData
}).fail(function(jqXHR) {
// Display errors on failure
$('#alerts').flashAlerts().done(function() {
// Re-enable submit button
form.enableSubmitButton();
});
});
});
想法是执行以下操作序列:
- POST表格。在请求之前,禁用提交按钮。请求完成后,
- 获取
alerts
api 中的错误。 that 请求完成后,显示错误消息。显示错误消息后, - 重新启用提交按钮。
这段代码似乎可以正常工作,但我不知道延期是否按正确的顺序工作(或者我是否只是对请求的时间感到幸运)。
所以,我这样做正确吗?我如何测试延期订单是否符合要求?
This code seems to work as it stands, but I have no idea if the deferrals are working in the correct order
是的,它们确实按预期工作。
So, am I doing this correctly?
不,您在 flashAlerts
方法中使用了 deferred antipattern。此外,您忽略从 ajax 请求到 /alerts
的错误,因此如果两个请求都失败,则不会重新启用该按钮。不确定这是否是您的意图,但我会在最后一次回调中使用 .always
而不是 .done
。
以下是我要写的内容:
$.fn.flashAlerts = function() {
var field = $(this);
return $.getJSON( "alerts", {})
.then(function(data) {
// Display alerts
field.html(data['message']);
return data;
});
};
How could I test that the deferral order is as desired?
没什么可测试的。通过您的代码布局方式,完全不可能在 $('#alerts').flashAlerts()
之前调用 form.enableSubmitButton();
或在 $.ajax({ … })
之前调用 $.getJSON( "alerts", {})
。当然,你必须相信那些在完成之前没有解决承诺的函数(这是你的代码工作所必需的),但执行顺序是无法逾越的。