dgh*_*dgh 19 javascript design-patterns asynchronous node.js
我的具体问题是我需要执行(可能)大量的Javascript函数来准备像批处理文件(每个函数调用将一些信息添加到同一个批处理文件),然后,在完成所有这些调用之后,执行一个发送批处理文件的最终函数(例如,将其作为HTML响应发送).我正在寻找一个通用的Javascript编程模式.
概括问题:鉴于Javascript函数funcA(),funcB()和funcC(),我想找出订购执行的最佳方法,这样funcC只能在执行funcA和funcB之后执行.我知道我可以使用这样的嵌套回调函数:
funcA = function() {
//Does funcA stuff
funcB();
}
funcB = function() {
//Does funcB stuff
funcC();
}
funcA();
Run Code Online (Sandbox Code Playgroud)
我甚至可以通过传递回调参数使这个模式更加通用,但是,这个解决方案变得非常冗长.
我也熟悉Javascript函数链接,解决方案可能如下所示:
myObj = {}
myObj.answer = ""
myObj.funcA = function() {
//Do some work on this.answer
return this;
}
myObj.funcB = function() {
//Do some more work on this.answer
return this;
}
myObj.funcC = function() {
//Use the value of this.answer now that funcA and funcB have made their modifications
return this;
}
myObj.funcA().funcB().funcC();
Run Code Online (Sandbox Code Playgroud)
虽然这个解决方案对我来说似乎有点清晰,但随着您向计算添加更多步骤,功能执行链变得越来越长.
对于我的具体问题,执行funcA,funcB等的顺序无关紧要.因此,在上面的解决方案中,我在技术上做了比工作要求更多的工作,因为我将所有功能放在一个串行排序中.对我来说最重要的是funcC(用于发送结果或触发请求的某些函数)仅在funcA和funcB完成所有执行后调用.理想情况下,funcC可以某种方式监听所有中间函数调用完成,然后执行?我希望学习一般的Javascript模式来解决这样的问题.
谢谢你的帮助.
另一个想法:也许将共享对象传递给funcA和funcB,当它们完成执行时,标记共享对象,如sharedThing.funcA ="complete"或sharedThing.funcB ="complete"然后以某种方式?当共享对象到达所有字段都标记为完成的状态时执行funcC.我不确定你怎么能让funcC等到这个.
编辑:我应该注意到我正在使用服务器端Javascript(Node.js),我想学习一种模式来解决它只是使用普通的旧Javascript(不使用jQuery或其他库).当然这个问题很普遍,有一个干净的纯Javascript解决方案吗?
如果您想保持简单,可以使用基于计数器的回调系统.这是一个允许when(A, B).then(C)语法的系统草案.(when/ then实际上只是糖,但整个系统可以说是.)
var when = function() {
var args = arguments; // the functions to execute first
return {
then: function(done) {
var counter = 0;
for(var i = 0; i < args.length; i++) {
// call each function with a function to call on done
args[i](function() {
counter++;
if(counter === args.length) { // all functions have notified they're done
done();
}
});
}
}
};
};
Run Code Online (Sandbox Code Playgroud)
用法:
when(
function(done) {
// do things
done();
},
function(done) {
// do things
setTimeout(done, 1000);
},
...
).then(function() {
// all are done
});
Run Code Online (Sandbox Code Playgroud)