【问题标题】:Error handling jQuery AJAX promises with Q使用 Q 处理 jQuery AJAX 承诺时出错
【发布时间】:2015-05-15 11:38:44
【问题描述】:

我在 AJAX 中使用 jQuery,但在我们的应用程序的其他地方使用 Q,因此希望确保 Promise 实现是一致的。

我已经用 Q 包装了 jQuery AJAX 调用,如下所示:

Q($.ajax(url, {
  type: 'get'
}));

而且对于成功响应来说一切正常。现在我想添加错误处理,我想要全局错误处理(因为我们的服务器有一致的错误响应),制作这样的 API:

var xhr = function (url) {
    return Q($.ajax(url, {
      type: 'get'
    }))
    .then(function (data) {
      return data;
    }, function (res) {
      //global error handling
    });
};

我希望这样使用它:

xhr('...').then(function () { console.log('success'); });

问题是当全局错误处理程序在调用xhr 方法的消费者上运行“成功”方法时。

你会如何防止这种情况发生?

可在此处查看可运行的示例 - http://jsbin.com/gudifu/3/edit

【问题讨论】:

标签: jquery ajax error-handling promise q


【解决方案1】:

由于 jQuery 的非标准 Promise,您必须跳过障碍将错误传递给 Q-coerced Promise。

首先,jqXHR 的错误签名是(jqXHR, textStatus, errorThrown),您通常希望传递第二个参数textStatus

其次,两个promise实现在错误处理方面有很大不同:

  • jQuery:传播错误状态,除非从 .then() 错误回调返回一个新的、已解决的承诺。 .fail() 保证传播错误状态,无论返回什么。未捕获的throw 将终止事件线程。
  • Q:将错误标记为“已处理”(即,将其发送到成功路径),除非 .catch().fail().then() 错误回调重新显示错误或抛出新错误,在在这种情况下,promise 会继续沿着错误路径前进。

因此,您需要:

  • .then(null, errHandler) 链接到您的jQuery.ajax() 呼叫以报告textStatus
  • 根据 jQuery 错误从 Q 中抛出错误
var xhr = function (url) {
    return Q($.ajax(url, {
      type: 'get'
    }).then(null, function(jqXHR, textStatus, errorThrown) {
        return textStatus;
    })).then(function (data) {
        return data;
    }, function (textStatus) {
      //global error handling
      throw new Error(textStatus);
    });
};

您也可以从 jQuery 中抛出一个适当的错误,然后从 Q 中重新抛出它。

var xhr = function (url) {
    return Q($.ajax(url, {
      type: 'get'
    }).then(null, function(jqXHR, textStatus, errorThrown) {
        return new Error(textStatus);
    })).then(function (data) {
        return data;
    }, function (err) {
      //global error handling
      throw err;
    });
};

两种解决方案的净效应将非常接近相同。我想我说得对,如果记录了错误,它们将显示不同的错误行号——前者源于 Q,后者源于 jQuery。

【讨论】:

    【解决方案2】:

    您的问题是全局错误处理程序处理错误。作为 Promise 链,您的 xhr(…) 承诺将通过错误处理程序返回的任何内容实现。就像catch,当异常处理完毕后,恢复正常执行。

    因此,您需要从处理程序中重新抛出异常,以便生成的 Promise 也被拒绝:

    var xhr = function (url) {
        return Q($.ajax(url, {
            type: 'get'
        }))
        .then(null, function (res) {
            //global error handling
            throw res;
        });
    };
    

    【讨论】:

    • 似乎在 jsbin 返回相同的结果?函数是否被调用了两次?
    • 是的。似乎在“runner-*”中被console 调用? :1 fail runner-3.25.21.min.js:1 pass through fail ?将尝试在 stacksn-ps、jsfiddle
    • @guest271314:我不知道你在说什么。 OP 的版本记录 fail - pass through success 而我的记录 fail - pass through fail 符合预期。
    • 是的,这里似乎没有正确解释问题。在 OP 上阅读、查看文章,并期望只有单个错误响应是,或者应该是期望的返回结果,原因。重新阅读您的答案并注意到“全局错误处理程序”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-12
    • 2015-04-08
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 2015-02-25
    • 2014-10-29
    相关资源
    最近更新 更多