我对异步javascript没有那么有经验。如何在不对命令数量进行硬编码或使用eval的情况下调用命令?
var commands = [
// command 1: result: 0, stdout: ""
function (stdin, callback) {
callback(0, "");
},
// command 2: result: 1, stdout: ""
function (stdin, callback) {
callback(1, "");
},
// command 3: result: 0, stdout: ""
function (stdin, callback) {
callback(0, "");
},
// ...
];
var stdin = "foo";
var end = function (result, stdout) {
console.log(result);
console.log(stdout);
};
commands[0](stdin, function (result, stdout) {
commands[1](stdout, function (result, stdout) {
commands[2](stdout, end);
});
});
答案 0 :(得分:2)
最终答案:
我正在使用递归来完成命令数组。 你传递一个循环函数一个命令数组和最后一个要调用的回调函数(你也可以作为第四个可选参数传递你想要启动循环的数组的索引 - 默认为零)。
var commands = [
// echo foo
function (stdin, callback) {
callback(0, "foo");
},
// touppercase
function (stdin, callback) {
callback(1, stdin.toUpperCase());
}
];
var stdin = "",
loop = function(commands, lastCallback, stdin, startIndex) {
(function insideLoop(i, stdout) {
commands[i](stdout, (i + 1 < commands.length) ? function(result, stdout){ insideLoop(i + 1, stdout); } : lastCallback);
})(startIndex || 0, stdin);
},
end = function (result, stdout) {
console.log(stdout);
};
loop(commands, end, stdin);
<强> Code Example 强>
答案 1 :(得分:0)
要让这些函数运行 asyncronously ,你需要一种方法来调用它们,确保在调用之间,允许浏览器(或实际上任何实现)做其他东西和事情(清理) ,回流等。)。
可以在浏览器中使用.setTimeout
或在nodejS中使用.nextTick
。
function runAsync( list ) {
(function _worker( method ) {
method();
if( list.length ) {
setTimeout(function() {
_worker( list.shift() );
}, 100);
}
}( list.shift() ));
}
这会被称为
runAsync( commands );
并且它将成功获取下一个数组条目(假定为函数)并执行它。之后,我们检查该条目中是否有更多元素,如果有,请抓住下一个并调用下一个函数。这种情况发生在setTimeout
来电和延迟 100ms 之间。我在这里选择 100ms ,因为它几乎是人类不会看到任何“减速”或“滞后”的时间框架。