【问题标题】:Check if function is jQuery ajax request检查函数是否为 jQuery ajax 请求
【发布时间】:2016-02-01 15:55:22
【问题描述】:

我正在编写一个 ajax 队列,我想确保函数的类型(来自一个对象)实际上是一个 ajax 请求,以便可以在其上调用 .done/.fail/.always。我该怎么做?

【问题讨论】:

  • 可以在问题中包含js 吗?
  • 您期望的值与 jQuery 承诺不同吗?

标签: javascript jquery ajax


【解决方案1】:

老问题,但我认为所有这些答案都非常不令人满意。 如果将来有人真的想检查传递的对象是否是 Promise,请尝试此功能。

function isPromise (obj) {
    const normal = !!obj && typeof obj === 'object' &&
                   ((obj.constructor && obj.constructor.name === 'Promise') || typeof obj.then === 'function');

    const fnForm = !!obj  && (typeof obj === 'function') && 
                   ((obj.name === 'Promise') || (typeof obj.resolve === 'function') && (typeof obj.reject === 'function'));

    return normal || fnForm;
}

适用于 ES6 Promise、Bluebird 和 jQuery ajax。

【讨论】:

    【解决方案2】:

    我想确保函数的类型(来自对象)实际上是一个 ajax 请求,以便可以在其上调用 .done/.fail/.always。

    jQuery ajax 请求对象 (jqXHR) 不是函数。在 jQuery v1.12.0(我方便检查的版本)中,它们是添加了属性的普通对象(例如,没有特殊的构造函数),因此您不能使用 instanceof 来查看它们是否是 jqXHR 对象.

    您可以测试您获得的对象上是否存在donefail 和/或always

    if (obj.done && obj.fail && obj.always) {
        // It's probably a jqXHR
    }
    

    或者,如果您想更彻底,您可以确保它们是函数:

    if (typeof obj.done == "function" &&
        typeof obj.fail == "function" &&
        typeof obj.always == "function") {
        // It's probably a jqXHR
    }
    

    这是“鸭子打字”的一个例子:它像鸭子一样嘎嘎叫,所以我们假设它是鸭子。

    如果您想真正将其尽可能限制为 jqXHR 对象而不是具有这些功能的其他事物,您可以检查它们具有的其他功能/属性,例如 getAllResponseHeaders 等。

    【讨论】:

      【解决方案3】:

      我以前用过这个:

      if(data && $.isFunction(data.promise)) {
      ...
      }
      

      我想确保函数的类型(来自对象)在 实际上是一个 ajax 请求,以便可以在其上调用 .done/.fail/.always。

      来自jQuery.ajax() 文档:

      从 jQuery 1.5 开始,由 $.ajax() 返回的 jqXHR 对象实现了 Promise 接口,给他们所有的属性、方法和 Promise 的行为(有关详细信息,请参阅 Deferred 对象)。

      jqXHR 对象的可用 Promise 方法包括:

      jqXHR.done(function(data, textStatus, jqXHR) {}); 另一种选择 构造成功回调选项, .done() 方法替换 已弃用的 jqXHR.success() 方法。请参阅 deferred.done() 了解 实现细节。

      jqXHR.fail(function(jqXHR, textStatus, errorThrown) {}); 一个 错误回调选项的替代构造,.fail() 方法 替换已弃用的 .error() 方法。请参阅 deferred.fail() 了解 实现细节。

      jqXHR.always(function(data|jqXHR, textStatus, jqXHR|errorThrown) { });* 完整回调选项的替代构造, .always() 方法替换了已弃用的 .complete() 方法。

      相关问题/答案:

      1. Any way to check whether a variable is a real jqXHR?
      2. How can I tell if an object is a jQuery Promise/Deferred?

      【讨论】:

        【解决方案4】:

        检查某个东西是否是一个承诺,或者在 jQuery 的情况下是一个 Deferred,可以通过检查该对象是否为 "thenable" 来完成,即它是否具有 then() 方法

        var xhr = $.ajax({url:'...'});
        
        if (typeof xhr === 'object' && typeof xhr.then === 'function') ...
        

        这适用于任何 Promise(也是 A+),以专门检查 jQuery ajax 调用始终具有的 faildonealways 方法,请参阅 T.J 的答案。

        【讨论】:

        • 对象可能具有then 属性,但不是$.ajax() 请求。 “我想确保函数的类型(来自一个对象)实际上是一个 ajax 请求”
        • 如果它在 jQuery 中有一个 then 方法,它就是一个 "thenable" Deferred/Promise,它有通常的回调,即使它不是一个 ajax 调用.
        • .done.fail.always 是延迟 api 的一部分,因此也不限于 ajax 请求。
        • 问题似乎试图确定返回的对象是否是$.ajax() 请求,而不仅仅是then 属性?请参阅 “我想确保函数类型(来自对象)实际上是 ajax 请求” 处的 OP
        • 如果它应该仅限于 ajax,可以按照 T.J. 的说明进行操作。上面,检查只有 ajax 调用具有的特定属性,例如 setRequestHeader 等。
        【解决方案5】:

        尝试检查status 属性,调用.state() 函数

        if (object.status && (obj.state() === "resolved" || obj.state() === "rejected")) {
              if (obj.status === 200) obj.done(success)
              else obj.fail(err)
        } else {
          // do other stuff
        }
        

        或者,使用.ajaxComplete(),应在完成$.ajax() 请求时调用

        所有ajaxComplete 处理程序都会被调用,不管是什么Ajax 请求已完成。如果您必须区分请求, 使用传递给处理程序的参数。每次ajaxComplete 处理程序被执行,它被传递事件对象, XMLHttpRequest 对象,以及在 创建请求。

        $(document).on("ajaxComplete", function(event, xhr, settings) {
           // do stuff
        })
        

        【讨论】:

        • @adeneo // do other stuff ;可以在else 处使用$.when(obj).always() 语句来表示既没有明确满足也没有拒绝的对象
        猜你喜欢
        • 1970-01-01
        • 2015-05-27
        • 2012-01-20
        • 2012-01-03
        • 2021-06-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多