原生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);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM