JavaScript引擎是基於單線程 (Single-threaded) 事件循環的概念構建的,同一時刻只容許一個代碼塊在執行,因此須要跟蹤即將運行的代碼,那些代碼被放在一個任務隊列 (job queue) 中,每當一段代碼準備執行時,都會被添加到任務隊列中。每當JavaScript引擎中的一段代碼結束執行,時間循環 (event loop) 會執行隊列中的下一個任務,它是 JavaScript 引擎中的一段程序,負責監控代碼執行並管理任務隊列。編程
請記住,隊列中的任務會從第一個一直執行到最後一個。promise
JavaScript最基礎的異步編程形式(好比點擊事件、鍵盤事件)
直到事件觸發時才執行處理程序異步
回調模式與事件模型相似,異步代碼都會在將來的某個時間點執行,而這的區別是回調模式中被調用的函數是做爲參數傳入的。
Node.js讀取磁盤上的文件:async
readFile('example.txt', function(err, contents) { if(err) { throw err } console.log(contents) }) console.log('Hi!')
調用readFile函數後,console.log('Hi!')語句會當即執行,當readFile結束執行的時候,會向任務隊列的末尾添加一個新任務,該任務包含回調函數及相應的參數。異步編程
雖然這個模式運行效果很不錯,可是若是嵌套了太多的回調函數,就會陷入回調地獄。函數
當須要跟蹤多個回調函數的時候,回調函數的侷限性就體現出來了,Promise很是好的改進了這些狀況。oop
Promise 對象是一個代理對象(代理一個值),被代理的值在Promise對象建立時多是未知的。它容許你爲異步操做的成功和失敗分別綁定相應的處理方法(handlers)。 這讓異步方法能夠像同步方法那樣返回值,但並非當即返回最終執行結果,而是一個能表明將來出現的結果的promise對象prototype
一個 Promise有如下幾種狀態:線程
pending: 初始狀態,既不是成功,也不是失敗狀態。 fulfilled: 意味着操做成功完成。 rejected: 意味着操做失敗。
pending 狀態的 Promise 對象可能觸發fulfilled 狀態並傳遞一個值給相應的狀態處理方法,也可能觸發失敗狀態(rejected)並傳遞失敗信息。當其中任一種狀況出現時,Promise 對象的 then 方法綁定的處理方法(handlers )就會被調用(then方法包含兩個參數:onfulfilled 和 onrejected,它們都是 Function 類型。當Promise狀態爲fulfilled時,調用 then 的 onfulfilled 方法,當Promise狀態爲rejected時,調用 then 的 onrejected 方法, 因此在異步操做的完成和綁定處理方法之間不存在競爭)。代理
由於 Promise.prototype.then 和 Promise.prototype.catch 方法返回promise 對象, 因此它們能夠被鏈式調用。
var promise1 = new Promise(function(resolve, reject) { setTimeout(function() { resolve('foo'); }, 300); }); promise1.then(function(value) { console.log(value); // expected output: "foo" }); console.log(promise1); // expected output: [object Promise]
當調用一個 async 函數時,會返回一個 Promise 對象。當這個 async 函數返回一個值時,Promise 的 resolve 方法會負責傳遞這個值;當 async 函數拋出異常時,Promise 的 reject 方法也會傳遞這個異常值。
async 函數中可能會有 await 表達式,這會使 async 函數暫停執行,等待 Promise 的結果出來,而後恢復async函數的執行並返回解析值(resolved)。
注意, await 關鍵字僅僅在 async function中有效。若是在 async function函數體外使用 await ,你只會獲得一個語法錯誤(SyntaxError)。
async function testAsync() { return "Hello"; } const testResult = testAsync(); console.log(testResult); //Promise { 'Hello' } testAsync().then(v => { console.log(v); // 輸出 Hello }); //使用await async function testAsnync1() { let result = await testAsync(); console.log(result); // Hello }
Promise() | MDN《深刻理解ES6》