zoukankan      html  css  js  c++  java
  • JS之异步概念

    概念 什么是JS异步

    异步加载也叫非阻塞模式加载,浏览器在下载js的同时,还会执行后续的页面处理.

    何时需要异步

    1 需要等待的情况

    2 在等待过程中不能像alert一样阻塞程序运行

    3 等待的情况需要异步

    使用场景:

    1 定时任务setTimeout, setInterval

    console.log(100);
     setTimeout(function(){
       console.log(200);
     },1000); //异步执行,非阻塞并不妨碍后续代码执行
     console.log(300);
    //执行顺序为100 300 200

    2   网络请求 ajax 动态<img> 加载

    console.log("start");
     var img=document.createElement("img");
     img.onload=function(){
       console.log("loaded");
     }
     img.src="https://ps.ssl.qhimg.com/sdmt/75_135_100/t01525fd8d9773b149f.jpg";
     document.body.append(img);
     console.log("end");
     //执行顺序是 start end loaded 图片的加载时异步的

    3  事件绑定

    console.log("start");
     document.getElementById("btn").addEventListener("click",function(){
       console.log("clicked");
     });
     console.log("end");
     //执行顺序是start ,end 如果点击才执行clicked 如果不点永远不执行 也是异步的

    典型的同步加载的例子:

    console.log(100);
     alert(200);
     console.log(300);
     //同步打印100,弹出200,打印300,取决于按下‘确定’框的时间,不按就一直卡顿在那

    同步或非同步,表明着是否需要将整个流程按顺序地完成

    阻塞或非阻塞,意味着你调用的函数会不会立刻告诉你结果

    二、在js中的阻塞与同异步

    你有一个函数和一段程序。

    2.1 js中的同步阻塞

    // 这是一个阻塞式函数, 将一个文件复制到另一个文件上
    function copyBigFile(afile, bfile){
        var result = copyFileSync(afile,bfile);
        return result;
    }

    调用这个”copyBigFile()”函数,将一个大文件复制到另一个文件上,将耗时1小时。意味着这个函数的将在一个小时之后返回。

    //这是一段程序
    console.log("start copying ... ");    
    var a = copyBigFile('A.txt', 'B.txt');  //这行程序将耗时1小时
    console.log("Finished");   // 这行程序将在一小时后执行
    console.log("处理一下别的事情");  // 这行程序将在一小时后执行
    console.log("Hello World, 整个程序已加载完毕,请享用"); // 这行程序将在一小时后执行

    以上的程序就是一个同步阻塞的例子,因为copyFileSync函数返回值的过程需要漫长的时间,所以线程也无法继续执行下去,只能等待。

    2.2 js中的同步非阻塞

    // 这是一个非阻塞式函数
    // 如果复制已完成,则返回 true, 如果未完成则返回 false
    function copyBigFile(afile,bfile){
        var copying = copyFileAsync(afile, bfile);
        var isFinished = !copying;
        return !isFinished; 
    }

    调用这个函数将立刻返回结果,然后你的程序就可以写成

    console.log("start copying ... ");    
    while( a = copyBigFile('A.txt', 'B.txt')){
      console.log("在这之间还可以处理别的事情");
    } ;  
    console.log("Finished");   // 这行程序将在一小时后执行
    console.log("Hello World, 整个程序已加载完毕,请享用"); // 这行程序将在一小时后执行

    一个非阻塞式的函数,给你的编程带来了更多的便利,你可以在长IO操作的同时,写点其他的程序,提高效率。执行结果如下

    start copying ...
    在这之间还可以处理别的事情
    在这之间还可以处理别的事情
    在这之间还可以处理别的事情
    ...
    Finished
    Hello World, 整个程序已加载完毕,请享用

    2.3 js中的异步非阻塞

    我们看到,一个非阻塞式的函数能给我们编程带来许多灵活性,我们喜欢非阻塞式的函数。 
    但是,又可以看到同步的程序需要在一个循环中轮询结果,循环里面的程序会被执行好多遍,所以并不好控制来写一些正常的程序,很难再利用起来。 
    所以我们需要一种更为合理的方式对非阻塞式的函数进行利用。 
    也就是我不会主动地去询问结果,而是当你有了结果的时候再来通知我。 
    // 这是一个非阻塞式函数 
    // 如果复制已完成,则返回 true, 如果未完成则返回 false

    //非阻塞式的有异步通知能力的函数
    //以下不需要看懂,只用知道这个函数会在完成copy操作之后,执行success
    function copyBigFile(afile,bfile, callback){
        var copying = copyFileAsync(afile, bfile, function(){ callback();});
        var isFinished = !copying;
        return !isFinished; 
    }

    这个函数不同于上一个同步非阻塞函数的地方在于,它具有通知功能,也就是说,它能够在完成操作之后主动地通知程序,“我完成了”。于是有程序如下,

    console.log("start copying ... ");    
    copyBigFile("A.txt","B.txt", function(){
              console.log("Finished");   //一个小时后被执行
              console.log("Hello World, 整个程序已加载完毕,请享用"); //一个小时后被执行
              })
    console.log("干别的事情"); 
    console.log("做一些别的处理"); 

    程序在调用copyBigFile函数之后,可以立即获得返回值,线程没有被阻塞住,于是还可以去干些别的事情,然后当copyBigFile完成之后,会执行指定的函数。所以程序的输出应为,

    start copying ...
    干别的事情
    做一些别的处理
    Finished
    Hello World, 整个程序已加载完毕,请享用

    在这种情况下,程序更容易控制,流程更为清晰。一些“别的事情”可以在函数还未通知之前进行处理,充分地提高了线程的利用效率。

      

       

  • 相关阅读:
    HttpModule和HttpHandler
    SharePoint
    两种遍历Hashtable方法(小技巧)
    在线游戏开发人员的行话
    AS3 条件编译
    Flash开发MMORPG的时候一些技术障碍
    Java实现几种常见排序方法
    画贝塞尔曲线
    一一解答
    如何留住核心人才?
  • 原文地址:https://www.cnblogs.com/xubj/p/7940631.html
Copyright © 2011-2022 走看看