我有一系列函数,如:
funcArray = [func1, func2, func3];
在给定函数中,我要在数组中执行下一个函数。我该怎么做呢?这是我的基本骨架:
function func1() {
// I get current function caller
var currentFunc = func1.caller;
// I want to execute the next function. Happens to be func2 in the example.
}
我不能使用indexOf
函数,就像字符串或数字数组一样。
注意:此问题似乎类似于this及其所指的问题。但是,这是一个不同的问题。
我想仅通过修改数组来更改处理顺序。这就是目标。可能会更有效的方法。
说明:基于一些评论: funcArray是全局的。
目标是以简单高效的方式为Node.js HTTP模块实现中间件,而无需使用任何第三方模块。
答案 0 :(得分:32)
除非func1
关闭funcArray
,否则您不能伸出手来找到func2
并执行它,也应该这样做。即使func1
确实在funcArray
结束,func1
的关注点分离仍很差,funcArray
会伸出手并在func2
中找到自己执行funcArray.forEach(fn => fn());
。
相反,还有其他代码负责运行这些功能。
如果这些函数同步完成其工作,则只需:
for (const fn of funcArray) {
fn();
}
或
reduce
或者如果一个函数的结果应该传递给下一个,则可以使用const finalResult = funcArray.reduce((previousResult, fn) => fn(previousResult), undefined);
:
undefined
...其中func1
是要传递给reduce
的值。
如果他们没有同步完成工作,则需要向他们提供一种方法,以通知呼叫者他们已经完成工作。承诺是一种很好的标准方法,但是您可以使用简单的回调。
例如,如果让它们返回承诺,则可以使用旧的承诺funcArray.reduce((p, fn) => {
return p.then(() => {
fn();
});
}, Promise.resolve());
技巧:
funcArray.reduce((p, fn) => {
return p.then(fn);
}, Promise.resolve());
或者是否将一个函数的结果传递给下一个:
Promise.resolve
您可以为func1
提供一个参数,以设置要传递给undefined
的值(如果没有,它将接收window.onpopstate
)。
答案 1 :(得分:4)
您可以将函数在数组中的索引绑定到该函数,以便可以使用此索引来获取并调用下一个函数:
var funcArray = [func1, func2];
var boundFuncArray = funcArray.map((f, i) => f.bind(null, i));
boundFuncArray[0]();
function func1(nextFunctionIndex) {
console.log('func1 called');
// Execute next function:
var nextFunc = boundFuncArray[nextFunctionIndex + 1];
nextFunc && nextFunc();
}
function func2(nextFunctionIndex) {
console.log('func2 called');
// Execute next function:
var nextFunc = boundFuncArray[nextFunctionIndex + 1];
nextFunc && nextFunc();
}
正如T.J Crowder在下面的评论中所述,您还可以将下一个函数绑定到当前函数:
var funcArray = [func1, func2];
var boundFuncArray= funcArray.map((f, i, arr) => f.bind(null, arr[i + 1]));
boundFuncArray[0]();
function func1(nextFunc) {
console.log('func1 called');
// Execute next function:
nextFunc && nextFunc();
}
function func2(nextFunc ) {
console.log('func2 called');
// Execute next function:
nextFunc && nextFunc();
}
答案 2 :(得分:3)
您可以使用arguments.callee.name
获取当前函数的名称,循环遍历函数数组,然后调用下一个函数:
funcArray = [func1, func2, func3];
// Only func1() and func2() will be documented since the others have repeating code
function func1() {
// show the current function name
console.log(arguments.callee.name);
// loop the array of functions
for(var i = 0; i < funcArray.length; ++i)
{
// when the current array item is our current function name and
// another function exists after this then call it and break
if(funcArray[i] === arguments.callee && funcArray[i+1])
{
funcArray[i+1]();
break;
}
}
}
function func2() {
console.log(arguments.callee.name);
// some logic which switches our next function to be func4()
funcArray[2] = func4;
for(var i = 0; i < funcArray.length; ++i)
{
if(funcArray[i] === arguments.callee && funcArray[i+1])
{
funcArray[i+1]();
break;
}
}
}
function func3() {
console.log(arguments.callee.name);
for(var i = 0; i < funcArray.length; ++i)
{
if(funcArray[i] === arguments.callee && funcArray[i+1])
{
funcArray[i+1]();
break;
}
}
}
function func4() {
console.log(arguments.callee.name);
for(var i = 0; i < funcArray.length; ++i)
{
if(funcArray[i] === arguments.callee && funcArray[i+1])
{
funcArray[i+1]();
break;
}
}
}
// call the first function
funcArray[0]();
输出:
func1
func2
func4
答案 3 :(得分:0)
我不知道您的函数是否需要某些参数,但这是我想到的第一件事。
var functArray = [
function() {
console.log("function1 executed");
},
function() {
console.log("function2 executed");
},
function() {
console.log("function3 executed");
},
function() {
console.log("function4 executed");
}];
functArray.forEach(function(x){
x();
});
答案 4 :(得分:0)
接受的答案和其他评论确实对我有所帮助,但是我的实现方式如下:
//The functions are defined as variables.
//They do not get hoisted, so must be defined first.
func1 = function (arg1, arg2) {
//Code to do whatever...
...
//Execute the next function.
//The name of the function is returned by executing nextFunc()
global[nextFunc()](arg1, arg2, arg3);
}
func2 = function (arg1) { //Note different type of args
...
}
//Note that this is an array of strings representing function names.
funcArray = ["func1", "func2", "func3",...]
//Start the execution...
func1(arg1, arg2);
function nextFunc() {
var currentFuncName = nextFunc.caller.name;
var index = funcArray.indexOf(currentFuncName);
if (index < funcArray.length)
return funcArray[index+1];
}
通过数组funcArray可以轻松管理要执行的功能序列。每个函数的参数数量或类型不是固定的。此外,功能控制它们是否应该停止链接或继续执行下一个功能。
了解基本的Java技能非常简单。没有使用Promises的开销。
对于浏览器,“全局”被“窗口”替换。这是一个Node.js实现。但是,如果最小化JS代码,则数组中函数名称的使用将中断。当我要在服务器上使用它时,我不希望将其缩小。