Javascript jsonpajax请求和jQuery.when()

Javascript jsonpajax请求和jQuery.when(),javascript,jquery,ajax,jsonp,.when,Javascript,Jquery,Ajax,Jsonp,.when,我必须进行一系列JSONP调用,并在它们全部完成(或失败)后执行一些代码 i、 e: 唯一的问题是,如果任何请求失败,将不会调用finished() 我可以尝试检测其中一个ajax调用是否失败,如下所示: function method1() { var method1_timeout = setTimeout(function() { // this call has failed - do something! }, 5000); var ajax

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

i、 e:

唯一的问题是,如果任何请求失败,将不会调用
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);
但是没有运气


有什么想法吗?

设置超时在JS的全局范围内,您在函数中创建了变量ajax。试一试

var method1_timeout = function(){ ajax.error();}
在函数中定义了var ajax,然后将method1\u timeout作为回调提供给setTimeout

setTimeout(method1_timeout, 5000);

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

因此,我想我在jQuery文档中找到了问题的答案,在
$.ajax
一章中:

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

检查JSONP返回的JS代码是否有效,检查控制台中是否存在任何语法错误,这些错误将停止您这边JS代码的执行(并阻止执行
始终
函数)


编辑:我重现了你的错误。使用jQuery2.x(edge)时,它的工作原理与预期的一样()。传递到jQuery 1.x(edge),这两个方法调用正在工作,但从未调用
始终
func()。我的所有测试都是在谷歌Chrome

下完成的,将第二个函数传递给
.then()
,如果出现错误(在底部),将调用该函数。或者,可能更喜欢使用promise的
fail
方法-失败的JSONP请求不会调用ajax
error()
方法,因此这不起作用。我已经将我的问题更新为使用
总是()
。我明白了,对不起,我没有意识到情况是这样的(我从来没有使用过JSONP),对不起,对于您的代码,您不想使用
ajax.error()
…您应该使用
ajax.reject()
(对于您似乎想要做的事情)-。这实际上改变了承诺的状态,这是承诺的回调方法所依赖的。
ajax
是实际的ajax对象,而不是
deferred
对象。。。调用
error()
只是一种猜测,我希望它会失败。我也不确定对延迟对象调用
reject()
是否是一个好主意,因为这会立即将状态更改为拒绝,并立即启动我的
finished()
方法,即使还有其他ajax请求等待处理。我认为两个jQuery分支应该具有相同的行为。那好像是个虫子?
setTimeout(method1_timeout, 5000);