Javascript:在转到第三个函数之前测试两个异步调用?

时间:2011-06-17 21:28:41

标签: javascript asynchronous

所以我有两个异步电话转到网络服务......我的第三个方法都需要它们。

你们怎么建议这样做?

我尝试在我的一个方法中设置一个标志(另一个方法调用第三个方法并发送一些数据)...所以在我的第三个方法中我尝试了这个:

 thirdMethod: function (returnedData) {

        if (this.secondFunctionReturned != true) {
            setTimeout(this.thirdMethod, returnedData, 100);
        }
        else {}

但是这个超时不起作用(它没有为我传递数据) - 只是想知道你们的想法......并且谢谢。

2 个答案:

答案 0 :(得分:11)

据推测,您正在从每个异步调用中获取数据,这就是为什么在触发第三个之前需要它们的原因。我将检查每个异步回调是否存在所有必需的数据,如果存在,则触发第三个函数。或者你可以使用一个计数器,但是再次,大概你已经有了数据,而计数器只是不必要的附加。

伪:

var dataFromCall1, dataFromCall2;

startAsync(function(data) {
    dataFromCall1 = data;
    if (dataFromCall2) {
        thirdFunction(dataFromCall1, dataFromCall2);
    }
});

startOtherAsync(function(data) {
    dataFromCall2 = data;
    if (dataFromCall1) {
        thirdFunction(dataFromCall1, dataFromCall2);
    }
});

或者更少耦合:

var dataFromCall1, dataFromCall2;

startAsync(function(data) {
    dataFromCall1 = data;
    nextStep();
});

startOtherAsync(function(data) {
    dataFromCall2 = data;
    nextStep();
});

function nextStep() {
    if (dataFromCall1 && dataFromCall2) {
        thirdFunction(dataFromCall1, dataFromCall2);
    }
}

或柜台:

var counter = 0;

startAsync(function() {
    // ...presumably some processing here...

    // Possibly fire next step
    handleCompletion();
});

startOtherAsync(function() {
    // ...presumably some processing here...

    // Possibly fire next step
    handleCompletion();
});

function handleCompletion() {
    if (++counter === 2) {
        thirdFunction();
    }
}

<强>更新

关于以下评论中的问题:

  

我尝试了一次,然后考虑了这两个实例同时返回的一个实例......如果它们都在同一时间返回,那么这种情况会不会失败?

好问题,我原本应该解决这个问题:不,两个呼叫都不可能同时发生。 Web浏览器中的JavaScript是单线程的(除非明确使用web workers,否则线程之间的交互是明确的)。如果第二次调用完成时第一次调用的回调正在进行中,则第二次回调将排队,并且仅在第一次回调返回时运行。

答案 1 :(得分:0)

我在T.J.投票支持反方法。克劳德的答案。

但是,另一个尚未建议的选项是,不是一次做两个调用,然后尝试将其与第三个调用同步,一次调用一个。也就是说,进行第一次异步调用并在其回调中进行第二次异步调用,然后在其回调中进行第三次调用。 (T.J.的计数器方法更具可扩展性。)

关于你提到的超时没有为你传递数据的问题,那是因为你试图向setTimeout传递太多的参数。你需要这样做:

setTimeout(function(){ this.thirdMethod(returnedData); },
           100);