摘要:而納入規范的也是建立在基礎上的。繼續閱讀的相關解釋語法其中函數擁有兩個參數和。可以看到,在語法上看,還是有點像回調函數那種形式的,囧。完成操作已經成功執行完畢。消費,即對的所代表的值進行一系列的處理。
文 | Leigh,UPYUN 已獲得授權
原文鏈接:http://t.cn/R403hc4
在 JavaScript 這么多年發展中,尤其在前端領域框架層出不窮,解決方案也琳瑯滿目,Promise 這個思想也逐漸從一個框架層面的實現變成了 ES 的規范,并且越來越多的新 API 都在以 Promise 為基礎制定。是時候來看看這個怪物了!
什么是 Promise在 JavaScript 尤其是前端開發領域,Promise 已經存在不少時日了,有一些曾經廣受好評的第三方庫,例如 Q,when,Bluebird,RSVP,基本都曾名噪一時,盡管實現方式/API 不一樣,但它們大多都遵循著 Promises/A+ 這個‘事實規范’。而納入 ES 規范的 Promise API 也是建立在 Promises/A+ 基礎上的。
要注意的是,jQuery 雖然有一個類似 Promise 的 API,但是它的 Promise 實際上是被稱作為 Deferred 對象的一個東西,它跟 Promises/A+ 的規范是不太兼容。
Promise 主要用來解決 JS 開發中的異步問題,而對異步的處理,社區中也有著不少的解決方案,最多的就是回調這種形式,比如,在 Node.js 中:
這種書寫上的約定,很容易解決對異步操作的處理,但缺陷是,這樣的寫法,我們沒發直接在異步函數中進行 return 和 throw 操作,只能局限于回調的形式中,并且很容易引起回調金字塔的情況。Promise 則對異步處理和處理方法都做了規范和抽象,還給了開發者在異步代碼中使用 return 和 throw 的能力。而這也是 Promise 存在的真正意義。繼續閱讀 domenic 的相關解釋
語法其中 executor 函數擁有兩個參數 resolve 和 reject。resolve 用于肯定 Promise,reject 用于否定它,我們可以在相關的操作結束后來執行這兩個函數。
可以看到,在語法上看,Promise 還是有點像回調函數那種形式的,囧。不過,和回調函數相比,它的主要不同點在于:
1、每一個 Promise 都保證能讓我們收到一個值,Promise 便是這個值的代理,而我們無需關心它被創建的時間點,我們更可以在任意時刻注冊我們的結果處理函數,即使這個 Promise 已經完成(resolved)了(這時候,所注冊的處理函數會被立即執行)。
2、每一個 Promise 都只會被成功或失敗一次,并且這個狀態不會被改變。
一個 Promise,會擁有以下幾個狀態之一:
1、pending(等待):操作正在執行中。
2、fulfilled(完成):操作已經成功執行完畢。
3、reject(失敗):操作執行失敗。
某些文章中可能會說到 settled 這個詞,settled 代表 Promise 不是 pending 的狀態,即:要么是 fulfilled,要么是 reject。但他本身并不是一個狀態,只是為了說的時候方便。詳見 domenic: States and Fates
Promise 的狀態變化圖如下:
使用 Promise創建
創建一個 Promise,直接的方法是直接 new Promise 創建一個,即上文中語法中所述一樣。其接受一個 executor 函數作為參數傳遞,Promise 在 executor 函數中提供了 resolve 和 reject 兩個函數供開發者根據實際結果來調用。
在 Promise 對象上,還有 Promise.all(iterable), Promise.race(iterable), Promise.reject(reason), Promise.resolve(value) 四個方法,這些方法也會返回 Promise 對象,因此,我們也可以通過這些方法來直接創建一個方法,例如 var p = Promise.resolve("I am a Promise!");
消費
Promise 一旦創建,我們就可以把它當做一個值來傳遞,因為 Promise 就是對一個未來會得到的值的代表。因此,你可以將它從函數中返回(return),也可以當做參數來傳遞到需要的地方,就像傳遞一個普通的值一樣。
消費 Promise,即對 Promise 的所代表的值進行一系列的處理。這里,我們可以使用 .then() 方法。
.then() 方法可以接受兩個函數作為參數,第一個參數的函數會在 Promise 完成(fulfilled)的時候被調用,而第二個參數的函數則在 Promise 失敗 (rejected)的時候調用。這兩個參數都是可以被省略的:
每個 Promise 實例還有一個 .catch() 方法,主要用于對錯誤的處理,對于 .catch() 的方法理解,其實很簡單,它就相當于 .then() 省略第一個參數:
上述兩種形式對錯誤的處理是等效的,當 Promise 失敗的時候,兩段代碼的執行結果一樣。不過,一般情況下,更加推薦使用 .catch() 方法來處理錯誤,因為 catch 本身名字更加直接易懂,并且,在鏈式調用 Promise 的時候,只需要在調用鏈最末端使用一個 .catch() 即可。
在 Promise 中,當直接 throw 一個異常的時候,將會使該 Promise 置為 rejected 狀態,這里需要注意的是,在 Promise 鏈中拋出異常,僅僅會將拋出異常所在的 Promise 置為 rejected,而不會影響原始的 Promise,比如:
處理多個異步操作
Promise.all()
在很多時候,我們都希望多個異步操作能夠并行,但很多情況下,我們又希望能在這多個異步操作全部都完成后再對結果進行處理,這個時候,我們就會用到 Promise.all(),這個方法接受一個 Promise 數組作為參數,且會在所有 Promise 完成后執行一次回調 .then(),在這里,所有數組中的 Promise 都是并行方式執行的,如下:
注意:只要一旦有一個 promise 失敗,.catch() 中的邏輯就會被執行。
Promise.all() 在一些大型 web app 中,將會很有用,因為大多良好的 API 設計都是以數據維度劃分,產品的某一個功能,可能會涉及到多個 API 的數據聯動,這時候,使用 Promise.all() 即可方便的解決。
Promise.race()Promise.race() 它同樣接受一個 Promise 數組作為參數,顧名思義,"race" 即比賽,想象一下,在平時百米競賽時候,一旦有人率先沖過終點,那變產生了一個冠軍,Promise.race() 即是在數組中的任意一個 Promise 完成后,便會觸發 .then() 的邏輯,當然,這里數組中的 Promise 也是并行的:
Promise.race() 的經典使用場景是某個服務有多個互備的形式,而我們需要盡快的拿到結果。
Series
并行很容易,但是 Promise 并沒有一個直接使用的串行的方法,當然,結合一些函數式編程的方法,我們可以很簡單的自行實現一下:
總結Promise 最近變得越來越火,無論前端領域,例如:Fetch API,Battery API,以及還未完成的 ServiceWorker API 等,甚至在 Node.js 社區中,人氣很高的 co,以及 koa 新版本都將 thunk 的形式改為了 Promise,在實際生產中投入使用,阻力也不會太大。
連接ES 規范
MDN 文檔
Can I Use 兼容性參考
es6-promise polyfill
歡迎關注 UPYUN 微信公眾號( ID : upaiyun ),我們每周都會分享高質量的原創技術文章。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78491.html
摘要:詳情發布于月號發布了版本,除了性能改進修復外,首次添加了貢獻者的安裝腳本。詳情中的應用在中悄悄增加了對漸進式應用這一系列新技術的基本支持,這意味著現在可以在沒有批準的情況下在上安裝應用程序,不過會有一些限制。 01. ES2016, 2017, 2018 中的新特性 文章介紹了 18 個 ECMAScript 2016,2017 和 2018 中新增加的特性,這些特性已被加入到 TC3...
摘要:詳情發布于月號發布了版本,除了性能改進修復外,首次添加了貢獻者的安裝腳本。詳情中的應用在中悄悄增加了對漸進式應用這一系列新技術的基本支持,這意味著現在可以在沒有批準的情況下在上安裝應用程序,不過會有一些限制。 01. ES2016, 2017, 2018 中的新特性 文章介紹了 18 個 ECMAScript 2016,2017 和 2018 中新增加的特性,這些特性已被加入到 TC3...
摘要:詳情發布于月號發布了版本,除了性能改進修復外,首次添加了貢獻者的安裝腳本。詳情中的應用在中悄悄增加了對漸進式應用這一系列新技術的基本支持,這意味著現在可以在沒有批準的情況下在上安裝應用程序,不過會有一些限制。 01. ES2016, 2017, 2018 中的新特性 文章介紹了 18 個 ECMAScript 2016,2017 和 2018 中新增加的特性,這些特性已被加入到 TC3...
摘要:本文總結了前端老司機經常問題的一些問題并結合個人總結給出了比較詳盡的答案。網易阿里騰訊校招社招必備知識點。此外還有網絡線程,定時器任務線程,文件系統處理線程等等。線程核心是引擎。主線程和工作線程之間的通知機制叫做事件循環。 showImg(https://segmentfault.com/img/bVbu4aB?w=300&h=208); 本文總結了前端老司機經常問題的一些問題并結合個...
閱讀 1873·2019-08-29 16:44
閱讀 2178·2019-08-29 16:30
閱讀 785·2019-08-29 15:12
閱讀 3534·2019-08-26 10:48
閱讀 2664·2019-08-23 18:33
閱讀 3784·2019-08-23 17:01
閱讀 1947·2019-08-23 15:54
閱讀 1308·2019-08-23 15:05