【问题标题】:Using jquery deferred promises inside plugins在插件中使用 jquery 延迟承诺
【发布时间】:2015-03-05 03:51:36
【问题描述】:

我编写了一个插件,它应该从 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. 发布表单。在请求之前,禁用提交按钮。请求完成后,
  2. alerts api 获取错误。一旦 那个 请求完成,就会显示错误消息。显示错误消息后,
  3. 重新启用提交按钮。

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

那么,我这样做对吗?如何测试延期订单是否符合要求?

【问题讨论】:

  • 作为一个快速而肮脏的解决方案,尝试在完成回调的主体中进行控制台日志记录。从那里您也可以检查提交按钮的状态。
  • 如果你正在使用一些东西来编写单元测试——比如 jasmine 或 qunit——会有一种更简洁的方法。
  • context 的预期值是什么,$.fn.flashAlerts() 的返回值?

标签: jquery ajax promise jquery-deferred


【解决方案1】:

这段代码似乎可以正常工作,但我不知道延期是否按正确的顺序工作

是的,它们确实按预期工作。

那么,我这样做对吗?

不,您在 flashAlerts 方法中使用了 deferred antipattern。此外,您会忽略来自对/alerts 的 ajax 请求的错误,因此如果两个请求都失败,则不会重新启用该按钮。不确定这是否是您的意图,但我会使用 .always 而不是 .done 进行最后一次回调。

这是我要写的:

 $.fn.flashAlerts = function() {
     var field = $(this);
     return $.getJSON( "alerts", {})
     .then(function(data) {
         // Display alerts
         field.html(data['message']);
         return data;
     });
 };

如何测试延期订单是否符合要求?

没有太多要测试的。通过您的代码布局方式,完全不可能在$('#alerts').flashAlerts() 之前调用form.enableSubmitButton();,或者在$.ajax({ … }) 之前调用$.getJSON( "alerts", {})。当然,您必须相信它们在完成之前不会解决承诺的那些函数(这是您的代码工作所必需的),但是执行顺序是不可逾越的。

【讨论】:

  • 谢谢,没有意识到我在使用反模式!
猜你喜欢
  • 2015-03-27
  • 2023-03-21
  • 1970-01-01
  • 2015-08-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
相关资源
最近更新 更多