在javascript中加入2个’主题’

如果我有一个ajax调用off(使用回调),然后在此期间运行其他一些代码。 如何在前两个完成时调用第三个函数。 我确定使用轮询(setTimeout然后检查一些变量)很容易,但我宁愿回调。

可能吗?

你可以给你的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. } } 

丹尼尔的解决方案是正确的。 我拿了它并添加了一些额外的代码,所以你不必考虑太多;)

 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); 

最好的方法是利用函数是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回调永远不会执行,直到发出请求的代码主体完成执行,即使在收到响应后很长时间。

如果不是你的情况,我在我的网站上创建了一个工作示例 ; 查看源代码以查看代码(就在标记之前)。 它发出的请求被服务器延迟了几秒钟,然后是一个接收立即响应的请求。 第二个请求的响应由一个函数处理,第一个请求的响应稍后由另一个函数处理,因为首先接收响应的请求已经改变了回调变量以引用第二个函数。

你正在谈论一个名为deferred in 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); 

像这样的东西(原理图):

 registerThread() { counter++; } unregisterThread() { if (--counter == 0) fireEvent('some_user_event'); } eventHandler_for_some_user_event() { do_stuff(); } 

您可以使用Google的Closure库轻松完成此操作,特别是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... }); 

您可以使用awaitDeferredchainDeferredgoog.async.DeferredList加入多个异步计算。