zoukankan      html  css  js  c++  java
  • 原生javascript实现异步的7种方式

    1、$(document).ready

      点评: 需要引用jquery ;兼容所有浏览器。

    2、标签的async=”async”属性

      async的定义和用法(是HTML5的属性)

      async 属性规定一旦脚本可用,则会异步执行。

      点评:HTML5中新增的属性,Chrome、FF、IE9&IE9+均支持(IE6~8不支持)。此外,这种方法不能保证脚本按顺序执行。 async 属性仅适用于外部脚本(只有在使用 src 属性时)。

    3、defer属性

    <script type="text/javascript" defer="defer"> 
    alert(document.getElementById("p1").firstChild.nodeValue); 
    </script> 

      点评:兼容所有浏览器。此外,这种方法可以确保所有设置defer属性的脚本按顺序执行

      asyncdefer看起来差不多呀?而且经常一起出现!来辨析一下

      (1)如果没有asyncdefer属性,那么浏览器会立即执行当前的JS脚本,阻塞后面的脚本;

      (2)如果有async属性,加载和渲染后续文档的过程和当前JS的加载与执行并行进行(异步),它是乱序执行的,不管你声明的顺序如何,只要它加载完了就会执行;

      (3)如果有defer属性,加载后续文档元素的过程和JS的加载是并行进行(异步)的,但是JS的执行在所有元素解析完成之后进行,而且它是按照加载顺序执行脚本的

    4、动态创建

    <!DOCTYPE html>
    <html>
        <head>
            <script type="text/javascript">
                (function(){
                    var s = document.createElement('script');
                    s.type = 'text/javascript';
                    s.src = "http://code.jquery.com/jquery-1.7.2.min.js";
                    var tmp = document.getElementsByTagName('script')[0];
                    tmp.parentNode.insertBefore(s, tmp);
                })();
            </script>
        </head>
        <body>
            <img src="https://images0.cnblogs.com/i/121863/201405/222202573569862.jpg" />
        </body>
    </html>

      原生的javascript 实现异步的方式其实远远不至7种, 大可以分3类:

      1、延迟类型:setTimeout(setInterval也是可以的)、requestAnimationFrame、setImmediate(IE10及以上)

      2、监听事件实现的类型:监听new Image加载状态、监听script加载状态、监听iframe加载状态、Message

      3、带有异步功能类型 Promise、ajax( XMLHttpRequest、ActiveXObject)、Worker;

      考虑到 :iframe 效率过慢; ajax 在ie下一定要加载真实的文件才能触发open及send;Worker 虽然具有异步特性,但它属于多线程的范畴,需要将主要的算法写在单独的js文件中才能完整体现其优点,若单单为了异步化而使用的话太浪费了。 所有这3种方式就不列出。

    一、实现异步的方式:

    1、setTimeout:这个是最简单的

    setTimeout( function() {
        console.log(1);
    });
    console.log(2);

    2、setImmediate :IE10添加的新功能,专门用于解放ui线程。IE10以下及其他浏览器不支持

    setImmediate(function(){
        console.log(1);
    });
    console.log(2);

    3、requestAnimationFrame :HTML5/CSS3时代新产物,专门用于动画。低级浏览器不支持

    var asynByAniFrame = (function(){
        var _window = window,
        frame = _window.requestAnimationFrame
                || _window.webkitRequestAnimationFrame
                || _window.mozRequestAnimationFrame
                || _window.oRequestAnimationFrame
                || _window.msRequestAnimationFrame;
        return function( callback ) { frame( callback ) };
    })();
    
    asynByAniFrame(function(){
        console.log(1);
    })
    console.log(2);

    4、监听new Image加载状态:通过加载一个data:image数据格式的图片,并监听器加载状态实现异步。

      尽管部分浏览器不支持data:image图片数据格式,但仍然可以触发其onerror状态实现异步,但IE8及以下对data:image数据格式的图片,onerror为同步执行

    function asynByImg( callback ) {
        var img = new Image();
        img.onload = img.onerror = img.onreadystatechange = function() {
            img = img.onload = img.onerror = img.onreadystatechange = null;
            callback(); 
        }
        img.src = "data:image/png,";
    }
    asynByImg(function(){
        console.log(1);
    });
    console.log(2);

    5、监听script加载状态

      原理同new Image是一样的,生成一个data:text/javascript的script,并监听其加载状态实现异步。

      尽管部分浏览器不支持data:text/javascript格式数据的script,但仍然可以触发其onerror、onreadystatechange事件实现异步。

    var asynByScript = (function() {
        var _document = document,
            _body = _document.body,
            _src = "data:text/javascript,",
            //异步队列
            queue = [];
        return function( callback ) {
                var script = _document.createElement("script");
                script.src  = _src;
                //添加到队列
                queue[ queue.length ] = callback;
                script.onload = script.onerror = script.onreadystatechange = function () {
                    script.onload = script.onerror = script.onreadystatechange = null;
                    _body.removeChild( script );
                    script = null;
                    //执行并删除队列中的第一个
                    queue.shift()();
                };
                _body.appendChild( script );
            }
    
        })();
    
    asynByScript( function() {
        console.log(1);
    } );
    console.log(2);

    6、Message:html5新技能,通过监听window.onmessage事件实现,然后postMessage发送消息,触发onmessage事件实现异步

    var asynByMessage = (function() {
            //异步队列
            var queue = [];
            window.addEventListener('message', function (e) {
                //只响应asynByMessage的召唤
                if ( e.data === 'asynByMessage' ) {
                    e.stopPropagation();
                    if ( queue.length ) {
                        //执行并删除队列中的第一个
                        queue.shift()();
                    }
                }
            }, true);
            return function( callback ) {
                //添加到队列
                queue[ queue.length ] = callback;
                window.postMessage('asynByMessage', '*');
            };
        })();
    
    asynByMessage(function() {
        console.log(1);
    });
    console.log(2);

    7、Promise: ES6的新技能,具有异步性质

    var asynByPromise = (function() {
            var promise = Promise.resolve({
                    then : function( callback ) {
                        callback();
                    }
                });
            return function( callback ) {
                        promise.then(function(){
                            callback();
                        })
                    };
        })();
    asynByPromise(function() {
        console.log(1);
    });
    console.log(2);

     

  • 相关阅读:
    vue-d2admin-axios异步请求登录,先对比一下Jquery ajax, Axios, Fetch区别
    beego 前后端分离登录验证
    Beego没gin配置静态页面方便
    beego-vue URL重定向(beego和vue前后端分离开发,beego承载vue前端分离页面部署)
    Go程序员面试算法宝典-读后感2-链表
    Go程序员面试算法宝典-读后感1
    bee api new
    golang-结构体的使用
    golang-笔记2
    golang-笔记1
  • 原文地址:https://www.cnblogs.com/goloving/p/9380136.html
Copyright © 2011-2022 走看看