【问题标题】:JSONP ajax request and jQuery.when()JSONP ajax 请求和 jQuery.when()
【发布时间】:2014-07-16 06:44:59
【问题描述】:

我必须进行一堆 JSONP 调用,并在它们全部完成(或失败)后执行一些代码。

即:

function finished() {
    alert('done!');
}

function method1() {
    return $.ajax('http://example.org/endpoint', {
        data: {
            foo: 'bar'
        },
        dataType: 'jsonp'
    });
}

function method2() {
    return $.ajax('http://example.org/endpoint', {
        data: {
            baz: 'qux'
        },
        dataType: 'jsonp'
    });
}

$.when(method1(), method2()).always(finished);

唯一的问题是,如果任何请求失败,finished() 将不会被调用。

我可以尝试检测其中一个 ajax 调用是否像这样失败:

function method1() {
    var method1_timeout = setTimeout(function() {
        // this call has failed - do something!
    }, 5000);

    var ajax = $.ajax('http://example.org/endpoint', {
        data: {
            foo: 'bar'
        },
        dataType: 'jsonp',
        success: function() {
            clearTimeout(method1_timeout);
        }
    });

    return ajax;
}

但我被困在了这一点上 - 我如何告诉延迟对象那个特定的 ajax 请求失败了?

我尝试调用 ajax 对象的error() 方法:

var method1_timeout = setTimeout(function() {
    ajax.error();
}, 5000);

但没有运气。

有什么想法吗?

【问题讨论】:

  • 将第二个函数传递给.then(),如果有错误将被调用 - api.jquery.com/jQuery.when(在底部)。或者,可能更喜欢使用 promise 的 fail 方法 - api.jquery.com/deferred.fail
  • 对于失败的 JSONP 请求不会调用 ajax error() 方法,所以这不起作用。我已更新我的问题以使用 always()
  • 我明白了,抱歉,我没有意识到是这样(我从来没有使用过 JSONP)
  • 抱歉,对于您的代码,您不想使用 ajax.error()...您会使用 ajax.reject() (对于您似乎想要做的事情) - api.jquery.com/deferred.reject 。这实际上改变了 Promise 的状态,这是 Promise 的回调方法所依赖的。
  • ajax 是实际的 ajax 对象,而不是 deferred 对象...调用 error() 只是一个猜测,我希望它会失败。我不太确定在延迟对象上调用reject() 是否是个好主意,因为这会将状态更改为立即拒绝,并立即触发我的finished() 方法,即使还有其他待处理的ajax 请求。

标签: javascript jquery ajax jsonp .when


【解决方案1】:

我在 jsFiddle 中“按原样”测试了您发布的代码,即使 JSONP 调用失败(当然,由于 example.com/endpoint 查询,请求返回 404 错误),它也能正常工作。

所以我想我在 $.ajax 章节中的 jQuery 文档中找到了您问题的答案:

服务器应返回传递 JSON 的有效 JavaScript 响应回调函数。 $.ajax() 将执行 返回 JavaScript,调用 JSONP 回调函数,之前 将响应中包含的 JSON 对象传递给 $.ajax() 成功处理程序。

检查您的 JSONP 返回的 JS 代码是否有效,并检查您的控制台中是否有任何语法错误会停止执行您的 JS 代码(并阻止执行 always 函数) .

编辑:我重现了您的错误。当使用 jQuery 2.x (edge) 时,它会像预期的那样工作 (try there)。传递给 jQuery 1.x (edge),这两个方法调用都在工作,但从未调用过 always 函数 (try there)。我所有的测试都是在 Google Chrome 下完成的。

【讨论】:

  • 我认为两个 jQuery 分支应该有相同的行为。这似乎是一个错误?
【解决方案2】:

setTimeouts 在 JS 的全局范围内,您在函数中创建了变量 ajax。试试

var method1_timeout = function(){ ajax.error();}

在您定义 var ajax 的函数内部,然后将 method1_timeout 作为回调提供给您的 setTimeout。

setTimeout(method1_timeout, 5000);

【讨论】:

    猜你喜欢
    • 2018-08-05
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 2015-06-22
    • 1970-01-01
    • 2011-09-22
    • 2013-03-28
    相关资源
    最近更新 更多