在本小節里,我們將不打算對瀏覽器實現的Promise進行說明,而是要介紹一些第三方實現的和Promise兼容的類庫。
## 4.1.1\. 為什么需要這些類庫?
為什么需要這些類庫呢?我想有些讀者不免會有此疑問。首先能想到的原因是有些運行環境并不支持?[ES6 Promises](http://liubin.github.io/promises-book/#es6-promises)?。
當我們在網上查找Promise的實現類庫的時候,有一個因素是首先要考慮的,那就是是否具有?[Promises/A+兼容性](http://liubin.github.io/promises-book/#promises-aplus)?。
[Promises/A+](http://liubin.github.io/promises-book/#promises-aplus)?是?[ES6 Promises](http://liubin.github.io/promises-book/#es6-promises)?的前身,Promise的?`then`?也是來自于此的基于社區的規范。
如果說一個類庫兼容 Promises/A+ 的話,那么就是說它除了具有標準的?`then`?方法之外,很多情況下也說明此類庫還支持?`Promise.all`和?`catch`?等功能。
但是 Promises/A+ 實際上只是定義了關于?`Promise#then`?的規范,所以有些類庫可能實現了其它諸如?`all`?或?`catch`?等功能,但是可能名字卻不一樣。
如果我們說一個類庫具有?`then`?兼容性的話,實際上指的是?[Thenable](http://liubin.github.io/promises-book/#Thenable)?,它通過使用?[Promise.resolve](http://liubin.github.io/promises-book/#Promise.resolve)?基于ES6 Promise的規定,進行promise對象的變換。
> ES6 Promise 里關于promise對象的規定包括在使用?`catch`?方法,或使用?`Promise.all`?進行處理的時候不能出現錯誤。
## 4.1.2\. Polyfill和擴展類庫
在這些Promise的實現類庫中,我們這里主要對兩種類型的類庫進行介紹。
一種是被稱為 Polyfill (這是一款英國產品,就是裝修刮墻用的膩子,其意義可想而知?—?譯者注)的類庫,另一種是即具有?[Promises/A+兼容性](http://liubin.github.io/promises-book/#promises-aplus)?,又增加了自己獨特功能的類庫。
> Promise的實現類庫數量非常之多,這里我們只是介紹了其中有限的幾個。
### Polyfill
只需要在瀏覽器中加載Polyfill類庫,就能使用IE10等或者還沒有提供對Promise支持的瀏覽器中使用Promise里規定的方法。
也就是說如果加載了Polyfill類庫,就能在還不支持Promise的環境中,運行本文中的各種示例代碼。
[jakearchibald/es6-promise](https://github.com/jakearchibald/es6-promise)
一個兼容 ES6 Promises 的Polyfill類庫。 它基于?[RSVP.js](https://github.com/tildeio/rsvp.js)?這個兼容 Promises/A+ 的類庫, 它只是 RSVP.js 的一個子集,只實現了Promises 規定的 API。
[yahoo/ypromise](https://github.com/yahoo/ypromise)
這是一個獨立版本的?[YUI](http://yuilibrary.com/)?的 Promise Polyfill,具有和 ES6 Promises 的兼容性。 本書的示例代碼也都是基于這個 ypromise 的 Polyfill 來在線運行的。
[getify/native-promise-only](https://github.com/getify/native-promise-only/)
以作為ES6 Promises的polyfill為目的的類庫 它嚴格按照ES6 Promises的規范設計,沒有添加在規范中沒有定義的功能。 如果運行環境有原生的Promise支持的話,則優先使用原生的Promise支持。
### Promise擴展類庫
Promise擴展類庫除了實現了Promise中定義的規范之外,還增加了自己獨自定義的功能。
Promise擴展類庫數量非常的多,我們只介紹其中兩個比較有名的類庫。
[kriskowal/q](https://github.com/kriskowal/q)
類庫?`Q`?實現了 Promises 和 Deferreds 等規范。 它自2009年開始開發,還提供了面向Node.js的文件IO API?[Q-IO](https://github.com/kriskowal/q-io)?等, 是一個在很多場景下都能用得到的類庫。
[petkaantonov/bluebird](https://github.com/petkaantonov/bluebird)
這個類庫除了兼容 Promise 規范之外,還擴展了取消promise對象的運行,取得promise的運行進度,以及錯誤處理的擴展檢測等非常豐富的功能,此外它在實現上還在性能問題下了很大的功夫。
Q 和 Bluebird 這兩個類庫除了都能在瀏覽器里運行之外,充實的API reference也是其特征。
* [API Reference · kriskowal/q Wiki](https://github.com/kriskowal/q/wiki/API-Reference)
Q等文檔里詳細介紹了Q的Deferred和jQuery里的Deferred有哪些異同,以及要怎么進行遷移?[Coming from jQuery](https://github.com/kriskowal/q/wiki/Coming-from-jQuery)?等都進行了詳細的說明。
* [bluebird/API.md at master · petkaantonov/bluebird](https://github.com/petkaantonov/bluebird/blob/master/API.md)
Bluebird的文檔除了提供了使用Promise豐富的實現方式之外,還涉及到了在出現錯誤時的對應方法以及?[Promise中的反模式](https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns)?等內容。
這兩個類庫的文檔寫得都很友好,即使我們不使用這兩個類庫,閱讀一下它們的文檔也具有一定的參考價值。
## 4.1.3\. 總結
本小節介紹了Promise的實現類庫中的 Polyfill 和擴展類庫這兩種。
Promise的實現類庫種類繁多,到底選擇哪個來使用完全看自己的喜好了。
但是由于這些類庫實現的 Promise 同時具有 Promises/A+ 或 ES6 Promises 共通的接口,所以在使用某一類庫的時候,有時候也可以參考一下其他類庫的代碼或者擴展功能。
熟練掌握Promise中的共通概念,進而能在實際中能對這些技術運用自如,這也是本書的寫作目的之一。
- 前言
- 第一章 - 什么是Promise
- 1.1. 什么是Promise
- 1.2. Promise簡介
- 1.3. 編寫Promise代碼
- 第二章 - 實戰Promise
- 2.1. Promise.resolve
- 2.2. Promise.reject
- 2.3. 專欄: Promise只能進行異步操作?
- 2.4. Promise#then
- 2.5. Promise#catch
- 2.6. 專欄: 每次調用then都會返回一個新創建的promise對象
- 2.7. Promise和數組
- 2.8. Promise.all
- 2.9. Promise.race
- 2.10. then or catch?
- 第三章 - Promise測試
- 3.1. 基本測試
- 3.2. Mocha對Promise的支持
- 3.3. 編寫可控測試(controllable tests)
- 第四章 - Advanced
- 4.1. Promise的實現類庫(Library)
- 4.2. Promise.resolve和Thenable
- 4.3. 使用reject而不是throw
- 4.4. Deferred和Promise
- 4.5. 使用Promise.race和delay取消XHR請求
- 4.6. 什么是 Promise.prototype.done ?
- 4.7. Promise和方法鏈(method chain)
- 4.8. 使用Promise進行順序(sequence)處理
- 第五章 - Promises API Reference
- 5.1. Promise#then
- 5.2. Promise#catch
- 5.3. Promise.resolve
- 5.4. Promise.reject
- 5.5. Promise.all
- 5.6. Promise.race
- 第六章 - 用語集
- 第七章 - 參考網站
- 第八章 - 關于作者
- 第九章 - 關于譯者