在?[ES6 Promises](http://liubin.github.io/promises-book/#es6-promises)?標準中定義的API還不是很多。
目前大致有下面三種類型。
**Constructor**
Promise類似于?`XMLHttpRequest`,從構造函數?`Promise`?來創建一個新建新`promise`對象作為接口。
要想創建一個promise對象、可以使用`new`來調用`Promise`的構造器來進行實例化。
~~~
var promise = new Promise(function(resolve, reject) {
// 異步處理
// 處理結束后、調用resolve 或 reject
});
~~~
**Instance Method**
對通過new生成的promise對象為了設置其值在?**resolve**(成功) /?**reject**(失敗)時調用的回調函數 可以使用`promise.then()`?實例方法。
~~~
promise.then(onFulfilled, onRejected)
~~~
resolve(成功)時:`onFulfilled`?會被調用
reject(失敗)時:`onRejected`?會被調用
`onFulfilled`、`onRejected`?兩個都為可選參數。
`promise.then`?成功和失敗時都可以使用。 另外在只想對異常進行處理時可以采用?`promise.then(undefined, onRejected)`?這種方式,只指定reject時的回調函數即可。 不過這種情況下?`promise.catch(onRejected)`?應該是個更好的選擇。
~~~
promise.catch(onRejected)
~~~
**Static Method**
像?`Promise`?這樣的全局對象還擁有一些靜態方法。
包括?`Promise.all()`?還有?`Promise.resolve()`?等在內,主要都是一些對Promise進行操作的輔助方法。
## 1.2.1\. Promise workflow
我們先來看一看下面的示例代碼。
promise-workflow.js
~~~
function asyncFunction() {
// `new`?Promise構造器之后,會返回一個promise對象
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('Async Hello world');
}, 16);
});
}
// 為promise對象用設置?`.then`?調用返回值時的回調函數。
asyncFunction().then(function (value) {
console.log(value); // => 'Async Hello world'
}).catch(function (error) {
console.log(error);
});
~~~
`asyncFunction`?這個函數會返回promise對象, 對于這個promise對象,我們調用它的?`then`?方法來設置resolve后的回調函數,?`catch`?方法來設置發生錯誤時的回調函數。
該promise對象會在setTimeout之后的16ms時被resolve, 這時?`then`?的回調函數會被調用,并輸出?`'Async Hello world'`?。
在這種情況下?`catch`?的回調函數并不會被執行(因為promise返回了resolve), 不過如果運行環境沒有提供?`setTimeout`?函數的話,那么上面代碼在執行中就會產生異常,在?`catch`?中設置的回調函數就會被執行。
當然,像`promise.then(onFulfilled, onRejected)`?的方法聲明一樣, 如果不使用`catch`?方法只使用?`then`方法的話,如下所示的代碼也能完成相同的工作。
~~~
asyncFunction().then(function (value) {
console.log(value);
}, function (error) {
console.log(error);
});
~~~
## 1.2.2\. Promise的狀態
我們已經大概了解了Promise的處理流程,接下來讓我們來稍微整理一下Promise的狀態。
用`new Promise`?實例化的promise對象有以下三個狀態。
"has-resolution" - Fulfilled
resolve(成功)時。此時會調用?`onFulfilled`
"has-rejection" - Rejected
reject(失敗)時。此時會調用?`onRejected`
"unresolved" - Pending
既不是resolve也不是reject的狀態。也就是promise對象剛被創建后的初始化狀態等
關于上面這三種狀態的讀法,其中 左側為在?[ES6 Promises](http://liubin.github.io/promises-book/#es6-promises)?規范中定義的術語, 而右側則是在?[Promises/A+](http://liubin.github.io/promises-book/#promises-aplus)?中描述狀態的術語。
基本上狀態在代碼中是不會涉及到的,所以名稱也無需太在意。 在這本書中,我們會基于?[Promises/A+](http://promises-aplus.github.io/promises-spec/)?中?_Pending_?、?_Fulfilled_?、_Rejected_?的狀態名稱進行講述。

Figure 1\. promise states
> 在?[ECMAScript Language Specification ECMA-262 6th Edition – DRAFT](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects)?中?`[[PromiseStatus]]`?都是在內部定義的狀態。 由于沒有公開的訪問?`[[PromiseStatus]]`?的用戶API,所以暫時還沒有查詢其內部狀態的方法。
到此在本文中我們已經介紹了promise所有的三種狀態。
promise對象的狀態,從_Pending_轉換為_Fulfilled_或_Rejected_之后, 這個promise對象的狀態就不會再發生任何變化。
也就是說,Promise與Event等不同,在`.then`?后執行的函數可以肯定地說只會被調用一次。
另外,_Fulfilled_和_Rejected_這兩個中的任一狀態都可以表示為**Settled**(不變的)。
Settled
resolve(成功) 或 reject(失敗)。
從_Pending_和_Settled_的對稱關系來看,Promise狀態的種類/遷移是非常簡單易懂的。
當promise的對象狀態發生變化時,用`.then`?來定義只會被調用一次的函數。
> [JavaScript Promises - Thinking Sync in an Async World // Speaker Deck](https://speakerdeck.com/kerrick/javascript-promises-thinking-sync-in-an-async-world)?這個ppt中有關于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
- 第六章 - 用語集
- 第七章 - 參考網站
- 第八章 - 關于作者
- 第九章 - 關于譯者