我们知道,在适用js的时候,程序是单线程执行的,而且如果遇到阻塞就会将浏览器卡死。
能否异步的执行,让程序不再卡呢?
可以,用setTimeout。
但是,问题又来了,如果我有这样的要求:
执行一个函数a;
暂停5秒;
执行函数b;
暂停5秒;
输出结果,暂停5秒后自动清空显示。
以上的这段逻辑伪代码使用JavaScript难以直接实现,因为setTimeout的时候,你根本不知道他什么时候执行结束。
jQuery有when方法可以解决问题,但是其嵌套性又让人伤神。
为此,我造了一个简单的轮子,发布出来,与开源社区共享。
轮子代码:
/** * * @authors sunsoft (sunruiyeyipeng@163.com) * @date 2015-04-30 22:26:22 * @version v1.0 */ function Executor() { return { oSequence: [], Params: {}, microInterval: 10, add: function(func, delay) { var that = this; var option = { delayInit: delay, startDateTime: null, state: "wait", delegateFunc: func, done: function() { this.state = "done"; }, getParam: function(paramname) { return that.Params[paramname]; }, setParam: function(paramname, value) { that.Params[paramname] = value; } }; this.oSequence.push(option); }, exec: function() { this.oSequence.reverse(); var that = this; //active the first one this.oSequence[that.oSequence.length - 1].startDateTime = new Date(); var fTmp = function() { if (that.oSequence.length > 0) { var oTask = that.oSequence[that.oSequence.length - 1]; if (oTask.state == "done") { //如果任务已经完成,就删除这个节点 that.oSequence.pop(); //如果还有下一个节点,则将它的开始时间设置好 if (that.oSequence.length > 0) { oTask = that.oSequence[that.oSequence.length - 1]; oTask.startDateTime = new Date(); } } if (oTask.state == "wait" && oTask.startDateTime != null && (new Date()) - oTask.startDateTime > oTask.delayInit) { oTask.state = "processing"; oTask.delegateFunc(oTask); } setTimeout(fTmp, that.microInterval); } else { console.log("done"); } } fTmp(); }, sleep: function(millSec) { this.add(function(task) { task.done(); }, millSec); } }; }
测试代码:
$(document).ready(function() { examples(); }); function examples() { var oExecutor = new Executor(); oExecutor.microInterval = 1; oExecutor.add(function(task) { //alert("we are the world"); console.log((new Date()).toLocaleString()) task.setParam("love","MJ"); task.done(); }, 0); oExecutor.sleep(2000); oExecutor.add(function(task) { console.log((new Date()).toLocaleString()) //alert("我又来了"); console.log(task.getParam("love")); task.done(); }, 0); oExecutor.exec(); }