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

[JavaScript]顺序的异步执行的更多相关文章

  1. 对Javascript异步执行的理解

    简单的查看了下Javascript异步编程的代码.按照网上的说法,Javascript异步编程的核心就在于setTimeout.这个系统函数让我们将函数的执行放在了一个指定的新“线程”中.于是本来的顺 ...

  2. 关于JavaScript预编译和执行顺序以及函数引用类型的思考

    昨晚在对项目中的一部分做模块化处理的时候,遇到了一个问题,一个重新定义的function对一个通用类中的function进行赋值覆盖的时候,失败了.问题抽象出来是这样的: <script > ...

  3. 高性能JavaScript 加载和执行

    前言 本章主要讲述如何加载脚本使得用户能有良好的用户体验,而核心内容就是JavaScript的异步加载.之前写过一篇不得不说的JavaScript异步加载,相似的内容就不多加描述,讲些不同的东西,主要 ...

  4. javascript延迟加载及异步(defer和async)

    一直以来写代码的时候的常用习惯就是吧所有的js文件直接加载在文档的head标签里面,在写js文件的时候有时候获取一些文件对象的时候为空对象,这是由于文档结构还没有加载完,但是js文件已经加载完.也就是 ...

  5. ajax同步、异步执行简单理解与证明

    此理解范例代码来自前几篇随笔! 首先我们来先了解下AJAX: Ajax:全称“Asynchronous Javascript and XML”(异步Javascript和XML),他是由Javascr ...

  6. javascript从定义到执行 js引擎 闭包

    javascript从定义到执行,JS引擎在实现层做了很多初始化工作,因此在学习JS引擎工作机制之前,我们需要引入几个相关的概念:执行环境 栈.全局对象.执行环境.变量对象.活动对象.作用域和作用域链 ...

  7. js文件引用方式及其同步执行与异步执行

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp74   任何以appendChild(scriptNode) 的方式引入 ...

  8. javascript中的异步 macrotask 和 microtask 简介

    javascript中的异步 macrotask 和 microtask 简介 什么是macrotask?什么是microtask?在理解什么是macrotask?什么是microtask之前,我们先 ...

  9. Go同步和异步执行多个任务封装

    同步执行类RunnerAsync 支持返回超时检测,系统中断检测 错误常量定义 //超时错误 var ErrTimeout = errors.New("received timeout&qu ...

随机推荐

  1. HTML中添加背景音乐

    <audio controls="controls" height="100" width="100"> <source ...

  2. maven环境快速搭建

    ----------------准备工作------------- Jdk  1.5以上java开发环境. Eclipse IDE 一个. Maven 3.0.3下载地址: http://maven. ...

  3. 【不积跬步,无以致千里】VIM查找替换归纳总结zz

    http://spaces.msn.com/dingy/blog/cns!2F24B9E66A542581!327.entry VIM中常用的替换模式总结. 1,简单替换表达式 替换命令可以在全文中用 ...

  4. tcpdump 本机回环,应该用tcpdump -i lo

    tcpdump  本机回环,应该用tcpdump -i lo

  5. MYSQL数据去重与外表填充

    经常要对数据库中的数据进行去重,有时还需要使用外部表填冲数据,本文档记录数据去重与外表填充数据. date:2016/8/17 author:wangxl 1 需求 对user_info1表去重,并添 ...

  6. Ceph之数据分布:CRUSH算法与一致性Hash

    转自于:http://www.cnblogs.com/shanno/p/3958298.html?utm_source=tuicool 数据分布是分布式存储系统的一个重要部分,数据分布算法至少要考虑以 ...

  7. [数据结构]Splay简介

    Splay树,又叫伸展树,可以实现快速分裂合并一个序列,几乎可以完成平衡树的所有操作.其中最重要的操作是将指定节点伸展到指定位置, 目录 节点定义 旋转操作 伸展操作 插入操作 删除操作 lower_ ...

  8. SELECT中(非常)常用的子查询操作

    MySQL中的子查询 是在MySQL中经常使用到的一个操作,不仅仅是用在DQL语句中,在DDL语句.DML语句中也都会常用到子查询. 子查询的定义: 子查询是将一个查询语句嵌套在另一个查询语句中: 在 ...

  9. 数据库入门(以MySQL为例)

    一.数据库中的概念 1.数据库是用户存放数据.访问数据.操作数据的存储仓库,用户的各种数据被有组织地存放在数据库中.可以随时被有权限的用户查询.统计.添加.删除.和修改.可以说,数据库是长期存储在计算 ...

  10. Lua热更新(hotfix)

    Lua热更新(hotfix)(金庆的专栏)hotfixLua 5.2/5.3 hotfix. Hot update functions and keep old data.https://github ...