在javascript中加入2个'主题'

时间:2009-05-30 11:50:42

标签: javascript jquery ajax multithreading join

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

有可能吗?

6 个答案:

答案 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...
});

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