詳談javascript非同步編程,詳談javascript非同步

來源:互聯網
上載者:User

詳談javascript非同步編程,詳談javascript非同步

非同步編程帶來的問題在用戶端Javascript中並不明顯,但隨著伺服器端Javascript越來越廣的被使用,大量的非同步IO操作使得該問題變得明顯。許多不同的方法都可以解決這個問題,本文討論了一些方法,但並不深入。大家需要根據自己的情況選擇一個適於自己的方法。

本文為大家詳細介紹js中的非同步編程,具體內容如下

一 關於事件的非同步

事件是JavaScript中最重要的一個特徵,nodejs就是利用js這一非同步而設計出來的。所以這裡講一下事件機制。

在一個js檔案中,如果要運行某一個函數,有2中手段,一個就是直接調用,比如foo(),第二就是利用事件來觸發,這中函數也叫回呼函數,比如傳遞給setTimeout函數和onready屬性。

1.setTimeout函數中的事件非同步
setTimeout本質上也是一種非同步事件,當延遲時間到的時候觸發該事件,但是有的有的時候(其實也是大部分時候)都不會按照給定的延遲時間執行,先看下面的代碼

  var start = new Date();  setTimeout(function() {   console.log('settimeout1:',new Date()-start);  }, 500);  while (new Date() - start < 1000) {   console.log('in while');  }  document.getElementById('test').addEventListener('click', function(){   console.log('test:',new Date()-start);  }, false)  for(var i=0;i<10000;i++){   console.log('in for');  }  setTimeout(function(){   console.log('settimeout2: ',new Date()-start);  },1000);  /* 10214  in while  index.jsp (第 19 行)  10000  in for  index.jsp (第 25 行)  settimeout1: 2263  index.jsp (第 16 行)  settimeout2: 3239  index.jsp (第 28 行)  test: 10006  index.jsp (第 22 行)  test: 28175  index.jsp (第 22 行)  test: 28791  index.jsp (第 22 行)  test: 28966  index.jsp (第 22 行) */

如果按照正常的理解,延遲函數應該在500毫秒之後打斷while迴圈,而事實上並沒有,並且,我在while迴圈和for迴圈期間點擊div時候並沒有立即輸出test,給出的解釋就是:

a)事件隊列。調用setTimeout函數的時候,會把傳入它的回呼函數加入到事件隊列中去(事件已經初始化並且在記憶體了),然後繼續執行後面的代碼,直到再也沒有代碼可以運行(沒有正常的運行流了,不包括事件函數等非同步內容),就會從事件隊列裡面pop出一個合適的事件來運行。

b)js是單線程的,事件處理器線上程空閑之前是不會啟動並執行。

2 普通事件的非同步和setTimeout類似
二 promise對象和deferred對象

1. promise
promise是一種解決ajax等非同步編程回呼函數嵌套太多導致代碼晦澀難懂的解決方案,特別是在nodejs中,非同步無處不在。不同的架構對promise的實現,一下是jquery中的promise的API。

這裡不講promise的實現原理,關於原理在另外的篇幅中介紹。

傳統的ajax非同步編程是這麼寫的(jquery1.5之前):

$.get('url', function(){ $.get('url1', function(){  $.get('url2', function(){  }, 'json'); }, 'json');}, 'json');

 這麼寫代碼給開發和維護帶來了極大的困難,好在jquery1.5以後引入了promise,就可以這麼寫了:

 $.ajax( "example.php" ).done(function() { alert("success"); }).fail(function() { alert("error"); }).always(function() { alert("complete"); });

 現在看上去就明顯簡單多了。

2.deferred對象

var nanowrimoing = $.Deferred();var wordGoal = 5000;nanowrimoing.progress(function(wordCount) {var percentComplete = Math.floor(wordCount / wordGoal * 100);$('#indicator').text(percentComplete + '% complete');});nanowrimoing.done(function(){$('#indicator').text('Good job!');});

三.worker對象和多線程

四.非同步指令碼載入

1.傳統指令碼在頁面中的位置
指令碼分為兩大類:阻塞式和非阻塞式。這裡的阻塞是指載入阻塞而不是運行阻塞。

<!DOCTYPE html><html><head><script src="headScript"></script><script defer src="deferredScript"></script></head><body> <script async defer src="chatWidget"></script> <script async defer src="asyncScript"></script></body></html>

上面這部分代碼是比較標準的關於指令碼在一個頁面中的位置,1.其中傳統的未加任何修飾的headScript是阻塞式的指令碼,由於瀏覽器從上到下解釋執行JavaScript,所以這部分指令檔在一開始就會被執行,並且在執行完之前是DOM是不會渲染的,但是head標籤裡面的css會載入。2.有defer屬性的指令碼會在DOM渲染的同時進行載入,但是會在DOM渲染完畢之後才開始執行,不幸的是,不是所有的瀏覽器都支援defer屬性,所以才會有了jquery(function)這個東西。3.同時帶有async屬性和defer屬性時候,defer會覆蓋async,但是單專屬async的時候,指令碼會在DOM渲染的時候載入並且運行。

2.可程式化的指令碼載入
如果不是一開始就在頁面種引入js檔案,而是通過使用者互動來實現動態載入js指令碼,可以通過編程方式加入。

瀏覽器擷取伺服器指令碼有2個方法,ajax擷取並且通過eval函數執行,另外一個就是在DOM中插入<script>標籤,一般用第二種方法,因為瀏覽器協助我們產生HTTP請求以及eval會泄露範圍。

var head = document.getElementsByTagName('head')[0];var script = document.createElement('script');script.src = '/js/feature.js';head.appendChild(script);script.onload = function() {// 現在可以呼叫指令碼裡定義的函數了}

以上就是本文的全部內容,希望對大家學習js非同步編程有所協助。

您可能感興趣的文章:
  • javascript非同步編程
  • JavaScript非同步編程:非同步資料收集的具體方法
  • javascript非同步編程的4種方法
  • JavaScript非同步編程Promise模式的6個特性
  • Javascript非同步編程模型Promise模式詳細介紹
  • Javascript中的非同步編程規範Promises/A詳細介紹
  • JavaScript中實現非同步編程模式的4種方法
  • node.js下when.js 的非同步編程實踐
  • 詳談nodejs非同步編程
  • Node.js 非同步編程之 Callback介紹(一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.