美文网首页
同步与异步

同步与异步

作者: 撕心裂肺1232 | 来源:发表于2018-08-08 20:49 被阅读0次

    提到异步,脑子里跳出来的第一个词是ajax异步加载,异步即相互不影响,总感觉异步离我很远,直到去看了相关的文档,瞬间恍然大悟。

    1. 单线程

    首先了解下,JavaScript是采用的是单线程模型(JavaScript 同时只能执行一个任务,其他任务都必须在后面排队等待)

    2. 同步任务和异步任务

    程序里面的所有任务,简单分成两类:同步任务(synchronous)和异步任务(asynchronous)。

    同步任务

    是那些没有被引擎挂起、在主线程上排队执行的任务。只有前一个任务执行完毕,才能执行后一个任务。

    异步任务

    是那些被引擎放在一边,不进入主线程、而进入任务队列的任务。只有引擎认为某个异步任务可以执行了(比如 Ajax 操作从服务器得到了结果),该任务(采用回调函数的形式)才会进入主线程执行。排在异步任务后面的代码,不用等待异步任务结束会马上运行,也就是说,异步任务不具有”堵塞“效应。
    (搬运过来的概念)

    口语化,同步就是一个一个地执行,后面的在排队等待。异步就是一个在执行,异步不在等待的队伍中,当达到了触发异步的点,异步被调用执行,异步执行完了继续按照原来的顺序来执行任务。

    3. 任务队列和事件循环

    首先,主线程会去执行所有的同步任务。等到同步任务全部执行完,就会去看任务队列里面的异步任务。如果满足条件,那么异步任务就重新进入主线程开始执行,这时它就变成同步任务了。等到执行完,下一个异步任务再进入主线程开始执行。一旦任务队列清空,程序就结束执行。

    异步任务的写法通常是回调函数。一旦异步任务重新进入主线程,就会执行对应的回调函数。如果一个异步任务没有回调函数,就不会进入任务队列,也就是说,不会重新进入主线程,因为没有用回调函数指定下一步的操作。

    (概念有点晕)

    4. 异步操作的几种模式

    4.1 回调函数
    同步:

    function f1() {
      // ...
    }
    
    function f2() {
      // ...
    }
    
    f1();
    f2();
    

    异步:

    function f1(callback) {
      // ...
      callback();
    }
    
    function f2() {
      // ...
    }
    
    f1(f2);
    

    4.2 事件监听
    异步的执行不取决于代码的顺序,而取决于某个事件(触发它的点)是否发生。

    f1.on('done', f2);
    function f1() {
      setTimeout(function () {
        // ...
        f1.trigger('done');
      }, 1000);
    }
    

    4.3 发布/订阅
    可以理解为事件监听的另一种形式。
    优势:可以通过查看“消息中心”,了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。

    jQuery.subscribe('done', f2);  //订阅
    function f1() {                       
      setTimeout(function () {
        // ...
        jQuery.publish('done');     //订阅
      }, 1000);
    }
    
    1. 异步操作的流程控制
      如果有多个异步操作,就存在一个流程控制的问题:如何确定异步操作执行的顺序,以及如何保证遵守这种顺序。
      5.1 串行执行
    var items = [ 1, 2, 3, 4, 5, 6 ];
    var results = [];
    
    function async(arg, callback) {
      console.log('参数为 ' + arg +' , 1秒后返回结果');
      setTimeout(function () { callback(arg * 2); }, 1000);
    }
    
    function final(value) {
      console.log('完成: ', value);
    }
    
    function series(item) {
      if(item) {
        async( item, function(result) {
          results.push(result);
          return series(items.shift());
        });
      } else {
        return final(results[results.length - 1]);
      }
    }
    
    series(items.shift());
    

    (一开始看了半个钟没get到点)
    5.2 并行执行
    流程控制函数也可以是并行执行,即所有异步任务同时执行,等到全部完成以后,才执行final函数。

    var items = [ 1, 2, 3, 4, 5, 6 ];
    var results = [];
    
    function async(arg, callback) {
      console.log('参数为 ' + arg +' , 1秒后返回结果');
      setTimeout(function () { callback(arg * 2); }, 1000);
    }
    
    function final(value) {
      console.log('完成: ', value);
    }
    
    items.forEach(function(item) {
      async(item, function(result){
        results.push(result);
        if(results.length === items.length) {
          final(results[results.length - 1]);
        }
      })
    });
    

    看完才知道,原来我日常写的都是异步!!只是没有一个很清晰的概念,有回调函数的都是异步啦(这样立即应该没错吧)
    5.3 并行与串行的结合
    所谓并行与串行的结合,就是设置一个门槛,每次最多只能并行执行n个异步任务,这样就避免了过分占用系统资源。
    (看到这感觉可以忽略掉后面的代码了)

    var items = [ 1, 2, 3, 4, 5, 6 ];
    var results = [];
    var running = 0;
    var limit = 2;
    
    function async(arg, callback) {
      console.log('参数为 ' + arg +' , 1秒后返回结果');
      setTimeout(function () { callback(arg * 2); }, 1000);
    }
    
    function final(value) {
      console.log('完成: ', value);
    }
    
    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(results);
          }
        });
        running++;
      }
    }
    
    launcher();
    

    记录此文,方便日后翻阅有关异步的相关知识点,大部分内容来源于网络。
    传送门:
    https://wangdoc.com/javascript/async/general.html#%E5%BC%82%E6%AD%A5%E6%93%8D%E4%BD%9C%E7%9A%84%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6

    相关文章

      网友评论

          本文标题:同步与异步

          本文链接:https://www.haomeiwen.com/subject/kwzxbftx.html