【问题标题】:Calling ajax as deferred promise and receiving errors调用 ajax 作为延迟承诺并接收错误
【发布时间】:2013-02-15 20:59:42
【问题描述】:

我正在尝试使以下代码工作,但我显然误解了 $.Deferred 的工作原理。请有人帮忙。

思路是,调用GetParameters,处理结果,调用GetStats,处理结果。还将busy 设置为true before 和false 设置为after。我预计只有一个错误会传播到 .fail()。

    self.refreshParams = $.ajax({
            url: self.ToAddress() + "/GetParameters",
            data: "{}",
            type: "GET",
            contentType: "application/javascript",
            dataType: "jsonp"
        });

    self.refreshMachines = $.ajax({
            url: self.ToAddress() + "/GetStats",
            data: "{}",
            type: "GET",
            contentType: "application/javascript",
            dataType: "jsonp"
      });

    self.refresh = function () {
      var d = $.Deferred();

      d.pipe(self.refreshParams)
      .done(function (p) {
          self.params(p);
      });

      d.pipe(self.refreshMachines)
      .done(function (m) {
          self.machines(m);
      });

      d.always(function() {
        self.busy(false);
      })
      .fail(function (x, e) {
          self.errorText(x);
      });

      d.resolve();
    }

更新:

我已将其更改为:

        self.refreshParams = function() {
          return $.ajax({
                url: self.ToAddress() + "/GetParameters",
                data: "{}",
                type: "GET",
                contentType: "application/javascript",
                dataType: "jsonp"
            });
        };

        self.refreshMachines = function() {
          return $.ajax({
                url: self.ToAddress() + "/GetStats",
                data: "{}",
                type: "GET",
                contentType: "application/javascript",
                dataType: "jsonp"
          });
        };

        self.refresh = function () {

          $.when(self.refreshParams(), self.refreshMachines())
          .done(function (p, m) {
              self.params(p[0]);
              self.machines(m[0]);
          })
          .done(function() {
            self.busy(false);
          })
          .fail(function (x, e) {
              self.errorText(x);
          });
        }

如果服务启动,这似乎可以工作,但如果出现错误,则没有任何问题可以归结为 .fail?

【问题讨论】:

    标签: jquery deferred promise


    【解决方案1】:

    编写这种类型的代码没有唯一的方法。

    您会发现为这两个 ajax 操作使用单独的 .done() 处理程序和 .fail() 处理程序会更好,从而使它们的成功和错误处理相互独立。

    然后,响应复合.when() 观察者所需要做的就是重置您的忙碌状态标志。通过在 .always() 处理程序中执行此操作,无论两个 ajax 操作的结果如何,它都会被重置。

    我可能会这样写:

    self.refresh = function () {
        self.busy(true);
    
        var paramsPromise = self.refreshParams().done(self.params).fail(function (jqXHR, textStatus, errorThrown) {
            self.errorText('refreshParams() : ' + textStatus + ' : ' + errorThrown);
        });
        var machinesPromise = self.refreshMachines().done(self.machines).fail(function (jqXHR, textStatus, errorThrown) {
            self.errorText('refreshMachines() : ' + textStatus + ' : ' + errorThrown);
        });
    
        $.when(paramsPromise, machinesPromise).always(function () {
            self.busy(false);
        });
    };
    

    【讨论】:

    • 但这完全滥用了承诺的链接/管道。我可以使用普通回调来编写这种代码。
    • "...完全误用..."?!?!?回到你的开场白,我不得不同意你很可能误解了 $.Deferred 的工作原理。你寻求建议,你收到了一些建议,但你完全不屑一顾。如果您不需要帮助,请不要发布问题。
    • 我可以看到我的评论可能会变得粗鲁,对此我很抱歉。非常感谢您的帮助,我确实非常感谢。在试图弄清楚这一天之后,我感到很沮丧。我的意思是误用,如果你必须定义和处理调用的错误和响应,它会打破链接的整个想法。
    • 姆拉登,接受道歉。我在回答中未能明确说明的一点是,在 .when() 子句中合成两个 jqXHR 会使事情变得过于复杂。首先,在.done() 回调中,您必须进行分支才能正确处理两个响应中的每一个。其次,在.fail() 回调中,您很难检测到两个ajax 请求中的哪一个失败了。在某些情况下,这种方法的局限性是不可避免的,但我认为情况并非如此。在将 jqXHR 放入 .when() 之前对其进行分配有助于提高可读性。
    猜你喜欢
    • 2013-04-27
    • 1970-01-01
    • 2018-08-15
    • 2015-03-08
    • 2015-03-27
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多