ECMAScript 6 的正式版後,咱們看到新增長了一個對象Promise
,它是用來處理異步操做的,之前的異步操做書寫並非很美觀,並且在回調函數中 return
和 throw
並不會帶到咱們想要的狀態。而Promise
很好的解決了這些問題。es6
promise 對象存在三種狀態,進行中、結束、失敗。當從進行中到結束狀態或從進行中到失敗狀態時,會觸發reslove
、reject
函數。promise
// 建立 promise let promise = new Promise(function(reslove,reject){ if(/ * 成功 */){ reslove(values) // 成功調用reslove函數 }else{ reject(values) // 失敗調用 reject函數 } }) // 調用 promise.then(function(val){ // 調用reslove() 函數 },function(val){ 調用 reject() 函數 })
reslove
和 reject
函數並不咱們本身聲明的,而是js底層爲咱們封裝好的。當咱們在 promise
對象中成功時調用reslove
函數,它會觸發then方法中的第一個函數,當咱們在 promise
對象中成功時調用reject
函數,它會觸發then方法中的第二個函數,另外then中的第二個方法咱們能夠省略。咱們可使用 catch
來接受一些錯誤信息。異步
promise.then((val) =>{ // 成功處理 }).catch((val) =>{ // 錯誤處理 })
在建立的promise
構造函數裏或then
的回調函數裏遇到的錯誤信息都會被catch
捕獲到,咱們來看一個例子函數
let promise = function(time){ return new Promise(function(relove, reject){ if(typeof time == 'number'){ setTimeout(relove,time,"調用成功"); }else{ reject("調用失敗") } }) } promise(100).then((val) =>{ console.log(val) // 調用成功 }) promise("fda").then((val) =>{ console.log(val) // 調用失敗 }) promise(100).then((val) =>{ new throw("出錯了") console.log(val) // 不執行 }).catch((val) => { console.log(val) //出錯了 })
如今咱們應該對promise有必定的瞭解,使用promise
還有必定的好處是,咱們能夠在then
回調函數中去使用 return
語句和 throw
語句,上面咱們已經使用了throw
語句。另外咱們還能夠在then的回調函數中去使用調用另外一 promise
對象。這樣比咱們使用AJAX交互時嵌套訪問清晰的多。code
promiseOne.then(()=>{ promiseTwo.then(() =>{ }) }).catch(() =>{ })
另外,咱們應該知道,then
方法和 catch
方法是綁定到了 promise
對象的原型上邊了。對象
1. Promise.all() 事件
該方法用於將多個 Promise 實例,包裝成一個新的 Promise 實例。ip
let promise = Promise.all([promiseOne,promiseTwo]);
這種狀況下當 promiseOne
和 promiseTwo
都成功調用 promise
纔會被成功調用,get
2. Promise.race() 原型
該方法一樣是將多個Promise
實例,包裝成一個新的Promise
實例。只不過在這種狀況下,只要其中一個被成功調用,promise
就會被成功調用。
將對象轉換爲 Promise
,這裏有四中狀況
(1)參數是一個Promise實例
let promise = new Promise(function(relove,reject){ }) // 返回promise let promiseNew = Promise.resolve(promise)
若是參數是Promise實例,那麼Promise.resolve將不作任何修改、原封不動地返回這個實例。
(2)參數是一個thenable對象
thenable對象就是帶有 then
方法的對象
let obj ={ then(relove,reject){ relove(111) } } let promiseNew = Promise.resolve(obj) promiseNew.then((val) =>{ console.log(val) // 111 })
這時Promise.resolve(obj)
會將obj轉化爲Promise
對象,並當即執行then方法
(3)參數不是具備then方法的對象,或根本就不是對象
let promiseNew = Promise.resolve(1234) promiseNew.then((val) =>{ console.log(val) // 1234 })
(4)不帶有任何參數
// 返回一個 relove狀態的Promise對象 let promiseNew = Promise.resolve()
須要注意的是,當即resolve
的Promise對象,實在事件循環結束時,而不是開始時,如:
setTimeout(function(){ console.log(111) }) Promise.resolve().then(() =>{ console.log(222) }) console.log(333) // 333 // 222 // 111
setTimeout
是在下一個事件循環時執行,Promise.reslove
是在事件循環結束是調用, console
是當即調用
Promise.reject(reason)
方法也會返回一個新的 Promise 實例,該實例的狀態爲rejected
。
var p = Promise.reject('出錯了'); // 等同於 var p = new Promise((resolve, reject) => reject('出錯了')) p.then(null, function (s) { console.log(s) }); // 出錯了
注意,Promise.reject()方法的參數,會原封不動地做爲reject的理由,變成後續方法的參數。這一點與Promise.resolve方法不一致。
該方法是Promise
對象的回調鏈,無論以then方法或catch方法結尾,要是最後一個方法拋出錯誤,都有可能沒法捕捉到(由於Promise內部的錯誤不會冒泡到全局)。所以,咱們能夠提供一個done方法,老是處於回調鏈的尾端,保證拋出任何可能出現的錯誤。
promise.then() .catch() .then() .catch() .done() // 接收錯誤,並向全局拋出
finally方法用於指定無論Promise對象最後狀態如何,都會執行的操做。它與done方法的最大區別,它接受一個普通的回調函數做爲參數,該函數無論怎樣都必須執行。
promise.then() .finally() // 無論then() 是否有錯,finally都會執行
promise 對象的使用並非很難,這裏我參考了阮一峯老師的書籍。
參考書籍:《ECMAScript 6 入門》