主要知識點:Promise生命週期、Promise基本操做、Promise鏈、響應多個Promise以及集成Promise
《深刻理解ES6》筆記 目錄
JavaScript引擎中,只有一個主線程,當執行JavaScript代碼塊時,不容許其餘代碼塊執行,而事件機制和回調機制的代碼塊會被添加到任務隊列(或者叫作堆棧)中,當符合某個觸發回調或者事件的時候,就會執行該事件或者回調函數。編程
瀏覽器初次渲染DOM的時候,咱們會給一些DOM綁定事件函數,只有當觸發了這些DOM事件函數,纔會執行他們:segmentfault
let button = document.getElementById("my-btn"); button.onclick = function(event) { console.log("Clicked"); };
當 Node.js 被建立時,它經過普及回調函數編程模式提高了異步編程模型。回調函數模式相似於事件模型,由於異步代碼也會在後面的一個時間點才執行:promise
readFile("example.txt", function(err, contents) { if (err) { throw err; } console.log(contents); }); console.log("Hi!");
若是回調過多,會陷入回調地獄;瀏覽器
Promise能夠當作是一個佔位符,表示異步操做的執行結果。函數能夠返回一個Promise,而沒必要訂閱一個事件或者向函數傳遞一個回調函數。異步
// readFile 承諾會在未來某個時間點完成 let promise = readFile("example.txt");
在此代碼中, readFile() 實際上並未當即開始讀取文件,這將會在稍後發生。此函數反而會返回一個 Promise 對象以表示異步讀取操做,所以你能夠在未來再操做它。異步編程
Promise的生命週期:進行中(pending),已經完成(fulfilled),拒絕(rejected)
每一個 Promise 都會經歷一個短暫的生命週期,初始爲掛起狀態(pending state) ,這表示異步操做還沒有結束。一個掛起的 Promise 也被認爲是未決的(unsettled )。一旦異步操做結束, Promise就會被認爲是已決的(settled ) ,並進入兩種可能狀態之一:函數
內部的[[PromiseState]] 屬性會被設置爲"pending" 、 "fulfilled" 或 "rejected",以反映Promise的狀態。該屬性並未在 Promise 對象上被暴露出來,所以你沒法以編程方式判斷 Promise 到底處於哪一種狀態。不過你可使用then()方法在 Promise 的狀態改變時執行一些特定操做。ui
then() 方法在全部的 Promise 上都存在,而且接受兩個參數。第一個參數是 Promise 被完成時要調用的函數,與異步操做關聯的任何附加數據都會被傳入這個完成函數。第二個參數則是 Promise 被拒絕時要調用的函數:spa
let promise = readFile("example.txt"); promise.then(function(contents) { // 完成 console.log(contents); }, function(err) { // 拒絕 console.error(err.message); }); promise.then(function(contents) { // 完成 console.log(contents); }); promise.then(null, function(err) { // 拒絕 console.error(err.message); });
其行爲等同於只傳遞拒絕處理函數給 then()線程
promise.catch(function(err) { // 拒絕 console.error(err.message); }); // 等同於: promise.then(null, function(err) { // 拒絕 console.error(err.message); });
Promise 使用 Promise 構造器來建立:
// Node.js 範例 let fs = require("fs"); function readFile(filename) { return new Promise(function(resolve, reject) { // 觸發異步操做 fs.readFile(filename, { encoding: "utf8" }, function(err, contents) { // 檢查錯誤 if (err) { reject(err); return; } // 讀取成功 resolve(contents); }); }); } let promise = readFile("example.txt"); // 同時監聽完成與拒絕 promise.then(function(contents) { // 完成 console.log(contents); }, function(err) { // 拒絕 console.error(err.message); });
romise構造函數接受一個函數做爲參數,該函數的兩個參數分別是resolve和reject。它們是兩個函數,由 JavaScript 引擎提供,不用本身部署。
執行器會在 readFile() 被調用時當即運行
let promise = new Promise(function(resolve, reject) { console.log("Promise"); resolve(); }); console.log("Hi!"); //輸出結果 Promise Hi!
Promise.resolve()方法接收一個參數,並會返回一個處於已完成狀態的 Promise ,在then()方法中使用完成處理函數才能提取該完成態的Promise傳遞的值,例如:
let promise = Promise.resolve(42); promise.then(function(value) { console.log(value); // 42 });
可使用Promise.reject()方法來建立一個已拒絕狀態的Promise,一樣只有在拒絕處理函數中或者catch()方法中才能接受reject()方法傳遞的值:
let promise = Promise.reject(42); promise.catch(function(value) { console.log(value); // 42 });