我有一个需要调用不确定数量的其他(可能是异步的)函数的函数,每个函数都带有回调,我正在使用以下模式.
虽然可以肯定这是正确的,但在美学上并不令人满意.
// fn responsible for figuring out and calling aysnc funcs function fn( arg, outNext ) { // calculate how many funcs we will be calling var waitCt = 0; var a, b, c; if( a = arg['a'] ) waitCt++; if( b = arg['b'] ) waitCt++; if( c = arg['c'] ) waitCt++; // call funcs if( a ) fnArbitrary( arg.a, inNext ); if( b ) fnRandom( arg, inNext ); if( c ) fnClueless( 15, inNext ); // calback func function inNext( err ) { // wait for one less func waitCt--; // return err if found if( err ) outNext( err ); // return nada if all funcs performed if( waitCt == 0 ) outNext(); // otherwise we're waiting for other funcs to finish return; } }
对我来说,似乎有必要采取两个步骤:第一步查看要调用的函子数,第二步进行调用.但是,也许我的大脑因过时的编程而感到厌倦,或者昨晚对Lear的阅读过多.
解决方法:
我见过的关于多个aysnc功能的最佳管理思想是Deferreds and Futures,如in this Script Junkie article、this article about the FutureJS implementation、this msdn article和Stack Overflow question所述.
实际上,这是一种结构化的思考方式,用于对多个异步调用进行排序或定义它们之间的执行依赖关系,并且对于不同的框架而言,它似乎正在进行多种实现(已经可用),因此似乎是一个普遍支持的想法,对于学习这两者都是很有用的.现在和将来.
手动管理多个具有依赖关系的异步调用确实很麻烦.代码不仅看起来凌乱,而且无法读取,甚至无法使用调试器.调试通常需要将大量信息转储到日志文件中,然后尝试找出发生的情况.如果涉及时间安排,那么您真的会一团糟.在我的上一个项目中,唯一仍然存在未解决的错误的地方是启动时四个不同的异步调用之间缺少某种依赖关系.我已经加强了代码使其能够执行,因此该错误几乎从未发生,但是还没有完全消失.下一步是切换到使用延期并为其添加一些正式结构.
至于一些更大的库,我们有jQuery Defereds,YUI3有Async Queue(虽然不如常规延迟功能强大,但很有用),Dojo有Deferred object,还有几个延迟库与主库无关.