js编程时经常会用到异步处理,而异步会带了所谓的并发问题。比如,你需要向服务器发出多个ajax请求,然后在返回所有结果后做进一步处理,同时要显示动画。因此我们需要用到以下的方案。
###【定义函数】
定义Batch函数。参数为函数组成的数组functions,这里面的函数将稍后执行,以及这些函数完成后的回调completionHandler。
1 2 3 4
| function Batch(functions, completionHandler) { this._functions = functions; this._completionHandler = completionHandler; }
|
###【启动请求】
用this._remaining来记录未执行的函数量,然后执行各个函数。
1 2 3 4 5 6 7 8 9
| Batch.prototype.execute = function execute() { var i; var functions = this._functions; var length = this._remaining = functions.length; this._results = []; for (i = 0; i < length; i += 1) { functions[i](this); } };
|
###【让Batch知道函数完成】
用this._results来记录执行结果,当this._remaining为0时,表示所有函数已执行完毕。
1 2 3 4 5 6 7 8 9
| Batch.prototype.done = function done(result) { this._remaining -= 1; if (typeof(result) !== 'undefined') { this._results.push(result); } if (this._remaining === 0) { this._completionHandler(this._results); } };
|
到这里,就完成了Batch这个函数的简单功能了。
###【使用】
将Batch应用到实际上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| var urls = [ '/api/gists/1000', '/api/gists/1001', '/api/gists/1002', '/api/gists/1003', '/api/gists/1004', '/api/gists/1337', ]; var i; var length = urls.length; var batchFunctions = []; for (i = 0; i < length; i += 1) { batchFunctions.push(function (batch) { $.ajax.get(urls[i], function (response) { batch.done(response); }); }); } var myBatch = new Batch(batchFunctions, function (results) { }); myBatch.execute();
|
这样的方案其实是参考了“观察者”模式。相关源码推荐nodeJs的Async.js库。
THE END.