在插件中使用 jquery 延迟承诺

Using jquery deferred promises inside plugins

我写了一个插件,它应该从 API 中获取错误消息并将它们显示在元素的 HTML 中。我想将它实现为一个承诺,以便其他事件可以通过 donealways 回调链接到它。插件的简化版本如下所示:

(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();
       });
    });
});

想法是执行以下操作序列:

  1. POST表格。在请求之前,禁用提交按钮。请求完成后,
  2. 获取 alerts api 中的错误。 that 请求完成后,显示错误消息。显示错误消息后,
  3. 重新启用提交按钮。

这段代码似乎可以正常工作,但我不知道延期是否按正确的顺序工作(或者我是否只是对请求的时间感到幸运)。

所以,我这样做正确吗?我如何测试延期订单是否符合要求?

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", {})。当然,你必须相信那些在完成之前没有解决承诺的函数(这是你的代码工作所必需的),但执行顺序是无法逾越的。