ES6 - Promise 對象

前言

ECMAScript 6 的正式版後,咱們看到新增長了一個對象Promise,它是用來處理異步操做的,之前的異步操做書寫並非很美觀,並且在回調函數中 returnthrow 並不會帶到咱們想要的狀態。而Promise 很好的解決了這些問題。es6

瞭解 promise

promise 對象存在三種狀態,進行中、結束、失敗。當從進行中到結束狀態或從進行中到失敗狀態時,會觸發reslovereject函數。promise

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() 函數
})

reslovereject 函數並不咱們本身聲明的,而是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對象的原型上邊了。對象

Promise 對象的其餘用法

1. Promise.all() 事件

該方法用於將多個 Promise 實例,包裝成一個新的 Promise 實例。ip

let promise = Promise.all([promiseOne,promiseTwo]);

這種狀況下當 promiseOnepromiseTwo 都成功調用 promise 纔會被成功調用,get

2. Promise.race() 原型

該方法一樣是將多個Promise實例,包裝成一個新的Promise實例。只不過在這種狀況下,只要其中一個被成功調用,promise 就會被成功調用。

  1. Promise.resolve()

將對象轉換爲 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 是當即調用

  1. Promise.reject()

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方法不一致。

  1. done()

該方法是Promise 對象的回調鏈,無論以then方法或catch方法結尾,要是最後一個方法拋出錯誤,都有可能沒法捕捉到(由於Promise內部的錯誤不會冒泡到全局)。所以,咱們能夠提供一個done方法,老是處於回調鏈的尾端,保證拋出任何可能出現的錯誤。

promise.then()
       .catch()
       .then()
       .catch()
       .done() // 接收錯誤,並向全局拋出
  1. finally()

finally方法用於指定無論Promise對象最後狀態如何,都會執行的操做。它與done方法的最大區別,它接受一個普通的回調函數做爲參數,該函數無論怎樣都必須執行。

promise.then()
       .finally() // 無論then() 是否有錯,finally都會執行

結束

promise 對象的使用並非很難,這裏我參考了阮一峯老師的書籍。

參考書籍:《ECMAScript 6 入門》

相關文章
相關標籤/搜索