談談Promise那點事(一)
隨著es6流行 Promise使用非常的廣泛 那那都是Promise 非同步請求返回一個Promise物件,Generator 中 yield 後面一般跟 Promise 物件, 等等到處都是Promise 我們真的搞明白了? 我們來簡單嘮嘮
Promise的規範
一個Promise 有三種狀態等待(pending)、已完成(fulfilled)、已拒絕(rejected)
一個promise的狀態只可能從“等待”轉到“完成”態或者“拒絕”態,不能逆向轉換,同時“完成”態和“拒絕”態不能相互轉換
- 一個Promise 有一個then方法
接收兩個可選函式引數onFulfilled、onRejected而且then必須返回一個promise,同一個promise的then可以呼叫多次,並且回撥的執行順序跟它們被定義時的順序一致
Promise的API
- 例項的方法
.then(resolvedFn, rejectFn)方法 .then 為Promise新增一個狀態改變時候的回撥 返回值一個新Promise的例項
.catch()方法 返回值也是一個Promise物件 Promise物件的錯誤具有冒泡性質 錯誤一直往後面傳遞 知道一直被這個 catch捕獲 正因為 這些例項方法都是Promise物件 所以可以通過鏈式呼叫 靜態的方法
Promise.resolve()方法將物件轉為Promise物件比如
var jsPromise = Promise.resolve($.ajax('/whatever.json')); Promise.resolve('foo') // 等價於 new Promise(resolve => resolve('foo'))複製程式碼
Promise.resolve() 方法引數有四種情況
- 如果引數是Promise例項 那返回也就是就是這個例項
如果返回時thenable 物件(含有then的物件) 則先將其轉換為promise物件,然後立即執行這個物件的then方法
let thenable = { then: function(resolve, reject) { resolve(42); } } let p1 = Promise.resolve(thenable); p1.then(function(value) { console.log(value); // 42 });複製程式碼
如果引數是個原始值,則返回一個promise物件,狀態為resolved,這個原始值會傳遞給回撥
var p = Promise.resolve('Hello'); p.then(function (s){ console.log(s) }); // Hello複製程式碼
沒有引數,直接返回一個resolved的Promise物件
var p = Promise.resolve(); p.then(function () { // ... }); 這裡p 就是Promise物件複製程式碼
Promise.reject()方法
同上,不同的是返回的promise物件的狀態為rejectedPromise.all()方法
Promise.all方法用於將多個 Promise 例項,包裝成一個新的 Promise 例項。var p = Promise.all([p1, p2, p3]);複製程式碼
這裡引數是陣列 p123都是Promise例項 如果不是Promise例項 會用到Promise.resolve() 轉為Promise例項
- 如果全部成功,狀態變為resolved,返回值將組成一個陣列傳給回撥
- 只要有一個失敗,狀態就變為rejected,返回值將直接傳遞給回撥
- 返回值也是個Promise例項
// 生成一個Promise物件的陣列 var promises = [2, 3, 5, 7, 11, 13].map(function (id) { return getJSON('/post/' + id + ".json"); }); Promise.all(promises).then(function (posts) { // ... }).catch(function(reason){ // ... });複製程式碼
上面解釋下 Promises是包含6個promise例項的陣列 這6個都變成都成功fulfilled 或者其中一個失敗rejected 都會呼叫all方法 後面回撥函式
這裡注意下若果自己定義了catch 捕獲 那麼在all裡面是捕獲不到的
- 例項的方法
Promise.race()方法
- 同上,區別是,只要有一個Promise例項率先發生變化(無論是狀態變成resolved還是rejected)都觸發then中的回撥,返回值將傳遞給回撥
- race()的返回值也是新的Promise物件
Promise初嘗一
參考連結ECMAScript 6 入門(阮一峰)