[JavaScript]顺序的异步执行

[JavaScript]顺序的异步执行

我们知道,在适用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();
}