如果我有一个ajax调用取回(使用回调),然后在此期间运行其他一些代码。如何在前两个函数完成时调用第三个函数。我确定使用轮询(setTimeout然后检查一些变量)很容易,但我宁愿回调。
有可能吗?
答案 0 :(得分:14)
你可以给你的AJAX调用和同时运行的其他代码提供相同的回调,使用变量跟踪他们的组合进度,然后将它们链接到如下所示的回调:
// Each time you start a call, increment this by one
var counter = 0;
var callback = function() {
counter--;
if (counter == 0) {
// Execute code you wanted to do once both threads are finished.
}
}
答案 1 :(得分:4)
丹尼尔的解决方案是正确的。我接受了它并添加了一些额外的代码,所以你不必考虑太多;)
function createNotifier() {
var counter = 2;
return function() {
if (--counter == 0) {
// do stuff
}
};
}
var notify = createNotifier();
var later = function() {
var done = false;
// do stuff and set done to true if you're done
if (done) {
notify();
}
};
function doAjaxCall(notify) {
var ajaxCallback = function() {
// Respond to the AJAX callback here
// Notify that the Ajax callback is done
notify();
};
// Here you perform the AJAX call action
}
setInterval(later, 200);
doAjaxCall(notify);
答案 2 :(得分:3)
最好的方法是利用函数是JavaScript中的一阶对象这一事实。因此,您可以将它们分配给变量并通过变量调用它们,根据需要更改变量引用的函数。
例如:
function firstCallback() {
// the first thing has happened
// so when the next thing happens, we want to do stuff
callback = secondCallback;
}
function secondCallback() {
// do stuff now both things have happened
}
var callback = firstCallback;
如果你的两段代码现在都使用变量来调用函数:
callback();
然后先执行的任何一个都会调用firstCallback,它会将变量更改为指向secondCallback,因此将以第二个执行的方式调用。
然而,你对这个问题的措辞意味着这可能都是不必要的,因为它听起来像是在发出Ajax请求然后继续处理。由于JavaScript解释器是单线程的,所以Ajax回调永远不会被执行,直到发出请求的代码主体完成执行,即使在收到响应后很长时间。
如果不是你的情况,我创建了一个working example on my site;查看源代码以查看代码(就在< / body>标记之前)。它发出的请求被服务器延迟了几秒钟,然后是一个接收立即响应的请求。第二个请求的响应由一个函数处理,第一个请求的响应稍后由另一个函数处理,因为首先接收响应的请求已经改变了回调变量以引用第二个函数。
答案 3 :(得分:3)
你正在谈论在javascript中被称为延迟的事情,如上面提到的@Chris Conway。类似地,jQuery也从v1.5开始延迟。
检查这些Deferred.when()或deferred.done()
不要忘记查看jQuery doc。
但是在这里给你一些想法是我从该网站复制的内容。
$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1, a2){
/* a1 and a2 are arguments resolved for the
page1 and page2 ajax requests, respectively */
var jqXHR = a1[2]; /* arguments are [ "success", statusText, jqXHR ] */
if ( /Whip It/.test(jqXHR.responseText) ) {
alert("First page has 'Whip It' somewhere.");
}
});
//使用deferred.then()
$.when($.ajax("/page1.php"), $.ajax("/page2.php"))
.then(myFunc, myFailure);
答案 4 :(得分:0)
像这样(原理图):
registerThread() {
counter++;
}
unregisterThread() {
if (--counter == 0) fireEvent('some_user_event');
}
eventHandler_for_some_user_event() {
do_stuff();
}
答案 5 :(得分:0)
您可以使用Google的Closure library轻松完成此操作,具体为goog.async.Deferred
:
// Deferred is a container for an incomplete computation.
var ajaxFinished = goog.async.Deferred();
// ajaxCall is the asynchronous function we're calling.
ajaxCall( //args...,
function() { // callback
// Process the results...
ajaxFinished.callback(); // Signal completion
}
);
// Do other stuff...
// Wait for the callback completion before proceeding
goog.async.when(ajaxFinished, function() {
// Do the rest of the stuff...
});
您可以使用awaitDeferred
,chainDeferred
或goog.async.DeferredList
加入多个异步计算。