Javascript:在进入第三个函数之前测试两个异步调用

Javascript : testing two asynch calls before going to third function?

本文关键字:测试 两个 调用 异步 函数 三个 Javascript      更新时间:2023-09-26

所以我有两个异步调用要调用一个Web服务。。。我的第三种方法需要这两种方法。

你们建议怎么做?

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

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

但这个暂停没有起作用(它没有为我传递数据)——只是想知道你们怎么想。。。谢谢。

假设您正在从每个异步调用中获取数据,这就是为什么在启动第三个调用之前需要它们的原因。我会让每个异步回调检查是否存在所有必需的数据,如果存在,则启动第三个函数。或者你可以使用一个计数器,但同样,假设你已经有了数据,计数器只是不必要的额外。

伪:

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工作程序,否则线程之间的交互也是显式的)。如果第二次调用完成时第一次调用的回调正在进行中,则第二次回调将排队,并且仅在第一次回调返回时运行。

我投票支持T.J.Crowder的答案中的计数器方法。

但是,另一个没有被建议的选择是,与其一次打两个电话,然后尝试与第三个同步,不如一次打一个电话。也就是说,进行第一个异步调用,并在其回调中进行第二个异步调用然后在其回调中将进行第三个调用。(T.J.的计数器方法可扩展性更强。)

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

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