• js的异步执行


    1.Javascript语言的执行环境是”单线程”(single thread):

    优点:实现起来比较简单,执行环境相对单纯;

    缺点:只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。

    为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)异步(Asynchronous)

    2.”异步模式”编程的几种方法:

    (1)回调函数:优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),使得程序结构混乱、流程难以追踪(尤其是回调函数嵌套的情况),而且每个任务只能指定一个回调函数。

    (2)采用事件驱动模式(事件监听):优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以”去耦合“(Decoupling),有利于实现模块化。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。

    (3)观察者模式(发布订阅模式):这种方法的性质与”事件监听”类似,但是明显优于后者。因为我们可以通过查看”消息中心”,了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。

    3.异步操作的流程控制。

    (1)串行执行:编写一个流程控制函数,让它来控制异步任务,一个任务完成以后,再执行另一个。

    var items = [ 1, 2, 3, 4, 5, 6 ];
    var results = [];
    function series(item) {
      if(item) {
        async( item, function(result) {
          results.push(result);
          return series(items.shift());
        });
      } else {
        return final(results);
      }
    }
    series(items.shift());

    函数series就是串行函数,它会依次执行异步任务,所有任务都完成后,才会执行final函数。items数组保存每一个异步任务的参数,results数组保存每一个异步任务的运行结果。

    (2)并行执行:所有异步任务同时执行,等到全部完成以后,才执行final函数。

    //forEach方法会同时发起6个异步任务,等到它们全部完成以后,才会执行final函数。
    var items = [ 1, 2, 3, 4, 5, 6 ];
    var results = [];
    
    items.forEach(function(item) {
      async(item, function(result){
        results.push(result);
        if(results.length == items.length) {
          final(results);
        }
      })
    });

    并行执行的好处是效率较高,比起串行执行一次只能执行一个任务,较为节约时间。但是问题在于如果并行的任务较多,很容易耗尽系统资源,拖慢运行速度。因此有了第三种流程控制方式。

    (3)并行与串行的结合:设置一个门槛,每次最多只能并行执行n个异步任务。这样就避免了过分占用系统资源。

    //变量running记录当前正在运行的任务数,只要低于门槛值,就再启动一个新的任务
    //如果等于0,就表示所有任务都执行完了,这时就执行final函数
    //最多只能同时运行两个异步任务。
    var items = [ 1, 2, 3, 4, 5, 6 ];
    var results = [];
    var running = 0;
    var limit = 2;
    
    function launcher() {
      while(running < limit && items.length > 0) {
        var item = items.shift();
        async(item, function(result) {
          results.push(result);
          running--;
          if(items.length > 0) {
            launcher();
          } else if(running == 0) {
            final();
          }
        });
        running++;
      }
    }
    
    launcher();

    如有错误,请您指正!

    参考文档:

    Promise对象

  • 相关阅读:
    持续集成之Jenkins+sonar自动化部署04
    自动化部署03
    自动化部署02
    自动化部署01
    持续集成之代码质量管理-Sonar
    gitlab-ce安装01
    在Centos7.3安装Zabbix3.4.4服务端
    自动化运维之日志系统上线规范(十)
    自动化运维之日志系统Logstash实践(九)
    自动化运维之日志系统Logstash解耦实践(八)
  • 原文地址:https://www.cnblogs.com/ksl666/p/5969154.html
Copyright © 2020-2023  润新知