Javascript 在$.Deferred.done()中,很快调用
这是一个例子来说明我的问题Javascript 在$.Deferred.done()中,很快调用,javascript,jquery,jquery-deferred,Javascript,Jquery,Jquery Deferred,这是一个例子来说明我的问题 $.fn.Heartbeat = function(){ console.log('started'); $.ajax({ url:baseurl.php, . . . success: function(data){ //DO SOME STUFF console.log('end of success'); } } $.when($('.mydiv').Heartbeat()).d
$.fn.Heartbeat = function(){
console.log('started');
$.ajax({
url:baseurl.php,
.
.
.
success: function(data){
//DO SOME STUFF
console.log('end of success');
}
}
$.when($('.mydiv').Heartbeat()).done(function(){console.log('after done');});
此代码输出:
已启动
完成后
成功结束
虽然我想:
已启动
成功结束
完成后
我的意思是,在Heartbeat完成之后必须执行DONE中的函数,否则它就不能完成 这是一种奇怪的方法,但是首先需要将
Heartbeat
函数添加到jQuery的原型中,以便能够链接它
其次,您需要将ajax函数中的承诺返回到$。当
时,只有在承诺解析时才会执行done
回调,如下所示
$.fn.Heartbeat = function () {
console.log('started');
return $.ajax({
url: 'baseurl.php',
success: function (data) {
//DO SOME STUFF
console.log('end of success');
}
});
}
$.when($('.mydiv').Heartbeat()).done(function () {
console.log('after done');
});
要为每个元素发送ajax请求,并在所有请求成功完成后解析承诺,可以执行以下操作
$.fn.Heartbeat = function () {
console.log('started');
var def = new Deferred();
$.when.apply(undefined,
$.map(this, function() {
return $.ajax({
url: '/echo/html/',
success: function (data) {
//DO SOME STUFF
console.log('end of success');
}
});
})
).then(def.resolve);
return def.promise();
}
$('.mydiv').Heartbeat().done(function () {
console.log('after done');
});
$。when()
不是魔术。它不知道传递给它的某个函数何时完成。相反,你必须给它一个承诺,然后它就会知道这个承诺何时兑现。因为您没有从Hearbeat()
函数返回承诺,$.when()
不知道ajax调用何时实际完成,因此它将其视为同步事件
以下是一种更简单的方法:
var Heartbeat = function(){
console.log('started');
return $.ajax({
url:baseurl.php,
// other args
}).then(function(data) {
//DO SOME STUFF
console.log('end of success');
});
}
Heartbeat().done(function(){
console.log('after done');
});
变化:
.done()
可以等待它$.when()
,只需对该承诺使用.then()
Heartbeat
是一个常规函数(不是jQuery方法),因此可以将其作为常规函数调用。由于该函数没有以任何方式使用jQuery对象,因此我认为没有任何理由将其作为jQuery方法。然后()
,因为您正在使用承诺抱歉,在我的代码中,我已经有了$.fn.Heartbeat,但是即使我返回promise@Ferex它确实有效,adeneo的代码与您在问题中发布的代码有一个词的不同,并且有效。我想这对你不起作用的原因是xhr失败了,它只打印出
start
,或者你正在使用你没有发布的代码,所以没有人能够猜测出哪里出了问题,因为你没有发布代码,也没有在评论中说出哪里出了问题它不起作用
不是描述问题的方法。而且您不需要$.when()
<代码>$('.mydiv').heartbeat().done(…)将完成此任务。(注意-我将“H”改为小写)。它成功了,我用done而不是then测试了它。然而,我不明白这里的重要教训。如果我不使用return怎么办?Heartbeat.done()不应该等待Heartbeat()完成吗?@Ferex done也可以,adeneo的答案也可以。如果复制代码,将其粘贴到控制台中,将“baseurl.php”更改为“”,然后在此页面上运行,您会发现它工作得很好。为什么你认为心跳应该返回一些东西?您需要将某个内容传递到where
,或者对某个内容调用done
。如果Heartbeat没有返回您试图调用的内容,则在未定义的上完成或将udefined传递到何处。很抱歉我的无知,但不是每个函数都返回内容吗??这就是我所想的:如果没有返回表达式,函数在完成时会返回true,而在其他情况下返回false。否。任何没有显式返回的函数都将返回undefined
@Ferex-没有显式返回语句的函数返回undefined
,因此您将undefined
传递给$。when()
$.when()
等待传递给它的承诺完成。如果您不向它传递任何承诺,它会认为一切都必须已经完成,因此它会立即执行.done()
回调,而不是等待ajax调用完成。