首页 > 解决方案 > 如何创建一个 Javascript 函数调用列表,在调用下一个函数之前等待前一个函数完成?

问题描述

我目前正在构建一个招牌系统,该系统以一致的格式显示各个位置的时间表信息。

这个想法是每个位置都有自己的轻量级页面,其中包含少量变量,这些变量定义了位置特定的参数,然后从单个外部 .js 文件中按顺序调用适当的函数。

我的页面与显式链接在一起的函数运行良好,如下所示:

function one (){        
    //do the thing
    two();      
}

function two (){        
    //do the next thing
    three();        
}

function three (){      
    //do the last thing
}   

我想要做的是分离函数,以便我可以从每个单独页面的列表中调用它们,这将让我根据不同位置的需要替换某些函数的不同版本。像这样的东西:

function callList(){     
  one();
  //wait for one to finish  
  two();
  //wait for two to finish 
  three();
}

我花了很多时间阅读有关异步函数、回调、承诺等的信息,但所提供的解决方案似乎仍然更多地处理将函数显式链接在一起并传递单个变量作为函数完成的证明,例如这个 (写得很好)例子:

https://flaviocopes.com/javascript-async-await/

找出正确解决方案的部分困难在于,我的功能的用途非常不同。我的许多函数根本不产生变量,而那些产生变量的函数(除了单个 ajax 调用)会产生大量不需要显式传递给下一个函数的全局参数。事实上,大多数人专注于以各种方式渲染和操作 svg 和文本,并且由于所显示数据的性质,许多人严重依赖循环。

与我遇到的大多数 javascript 问题一样,我确信这只是我理解上的一个差距,但我觉得我只是一遍又一遍地阅读相同的文章,却一无所获。我真的需要一个更有知识的人来推动我朝着正确的方向前进。

谢谢。

标签: javascriptjquery

解决方案


函数是 Javascript 中的一等公民,因此您可以将它们放入数组中,然后循环调用它们。

var functionsToCall = [
    one,
    two,
    three
];

// Call them (use your looping method of choice)
for (var i = 0; i < functionsToCall.Length; i++) {
    functionsToCall[i]();
}

如果您的函数是同步的并且没有返回您需要的任何内容,那么这基本上就是您所需要的。如果您的函数是异步的,那么您可能需要更多类似的东西await functionsToCall[i]();或使用承诺/回调的设置。

如果你需要回调来告诉你一个函数何时完成,你可以使用一个小的状态管理器/函数来处理它(或者如果你的环境支持它们,你可以使用 async/await - 它们写起来更干净!:)) .

就像是...

// A sample async function - you pass the callback to it.
function one(callback) {
    // Do some async work, like AJAX...

    // Let the callback know when I'm finished (whether I have a value to return or not.
    callback();
}

// Simple state management - wrap these up with nicer code and handle errors and whatnot.
var funcIndex = 0;
function callNext() {
    if (funcIndex < functionsToCall.Length) {
        functionsToCall[funcIndex](callNext);
        funcIndex += 1;
    }
}

// To start things off:
function callAllFunctions() {
    funcIndex = 0;
    callNext();
}

如果您需要对函数调用进行更精细的控制,您可以将自定义对象放入数组中,而不仅仅是函数本身,并据此更改行为。

例如:

var functionsToCall = [
    { func: one, isAsync: true },
    { func: two, isAsync: false }
];

无论如何,只是一些可能性。这实际上取决于您对特定情况的需要!


推荐阅读