javascript語言是一門「單線程」的語言,不像java語言,類繼承Thread再來個thread.start就能夠開闢一個線程,因此,javascript就像一條流水線,僅僅是一條流水線而已,要麼加工,要麼包裝,不能同時進行多個任務和流程。javascript
因此同步和異步,不管如何,作事情的時候都是隻有一條流水線(單線程),同步和異步的差異就在於這條流水線上各個流程的執行順序不一樣。java
一、最基礎的異步是setTimeout和setInterval函數,很常見,可是不多人有人知道其實這就是異步,由於它們能夠控制js的執行順序。咱們也能夠簡單地理解爲:能夠改變程序正ajax
常執行順序的操做就能夠當作是異步操做promise
1 <script type="text/javascript"> 2 console.log( "1" ); 3 setTimeout(function() { 4 console.log( "2" ) 5 }, 0 ); 6 setTimeout(function() { 7 console.log( "3" ) 8 }, 0 ); 9 setTimeout(function() { 10 console.log( "4" ) 11 }, 0 ); 12 console.log( "5" ); 13 </script>
輸出順序:瀏覽器
在執行程序的時候,瀏覽器會默認setTimeout以及ajax請求這一類的方法都是耗時程序(儘管可能不耗時),將其加入一個隊列中,該隊列是一個存儲耗時程序的隊列,網絡
在全部不耗時程序執行事後,再來依次執行該隊列中的程序。異步
二、又回到了最初的起點——javascript是單線程。單線程就意味着,全部任務須要排隊,前一個任務結束,纔會執行後一個任務。若是前一個任務耗時很長,後一個任務就不async
得不一直等着。因而就有一個概念——任務隊列。若是排隊是由於計算量大,CPU忙不過來,倒也算了,可是不少時候CPU是閒着的,由於IO設備(輸入輸出設備)很函數
慢(好比Ajax操做從網絡讀取數據),不得不等着結果出來,再往下執行。因而JavaScript語言的設計者意識到,這時主線程徹底能夠無論IO設備,掛起處於等待中的任spa
務,先運行排在後面的任務。等到IO設備返回告終果,再回過頭,把掛起的任務繼續執行下去。
因而,全部任務能夠分紅兩種,一種是同步任務(synchronous),另外一種是異步任務(asynchronous)。同步任務指的是,在主線程上排隊執行的任務,只有前一個任務
執行完畢,才能執行後一個任務;異步任務指的是,不進入主線程、而進入"任務隊列"(task queue)的任務,只有等主線程任務執行完畢,"任務隊列"開始通知主線程,
請求執行任務,該任務纔會進入主線程執行。
Promise
的真正強大之處在於它的多重鏈式調用,能夠避免層層嵌套回調
Promise
對象表明一個未完成、但預計未來會完成的操做。
它有如下三種狀態:
pending
:初始值,不是fulfilled,也不是rejectedfulfilled
:表明操做成功rejected
:表明操做失敗/* 例3.1 */ //構建Promise var promise = new Promise(function (resolve, reject) { if (/* 異步操做成功 */) { resolve(data); } else { /* 異步操做失敗 */ reject(error); } });
相似構建對象,咱們使用new
來構建一個Promise
。Promise
接受一個「函數」做爲參數,該函數的兩個參數分別是resolve
和reject
。這兩個函數就是就是「回調函數」,由JavaScript引擎提供。
resolve
函數的做用:在異步操做成功時調用,並將異步操做的結果,做爲參數傳遞出去; reject
函數的做用:在異步操做失敗時調用,並將異步操做報出的錯誤,做爲參數傳遞出去。
Promise實例生成之後,能夠用then
方法指定resolved
狀態和reject
狀態的回調函數。
/* 接例3.1 */ promise.then(onFulfilled, onRejected); promise.then(function(data) { // do something when success }, function(error) { // do something when failure });
then
方法會返回一個Promise。它有兩個參數,分別爲Promise從pending
變爲fulfilled
和rejected
時的回調函數(第二個參數非必選)。這兩個函數都接受Promise對象傳出的值做爲參數。
簡單來講,then
就是定義resolve
和reject
函數的,其resolve
參數至關於:
function resolveFun(data) { //data爲promise傳出的值 }
而新建Promise中的'resolve(data)',則至關於執行resolveFun函數。
Promise新建後就會當即執行。而then
方法中指定的回調函數,將在當前腳本全部同步任務執行完纔會執行。