關於promise的小結

Promise

本文從js的異步處理出發,引入Promise的概念,而且介紹Promise對象以及其API方法。segmentfault

js裏的異步處理

能夠參考這篇文章
js是單線程的,
在js裏,異步處理總共有四種方法,其中最多見的一種方法是採用回調函數的方式數組

function f1(callback){
    setTimeout(function(){
        callback();
    },1000)
}

f1(f2);

另外除了回調函數,事件監聽的機制也會進行異步處理。任務的執行不取決於代碼的順序,而是取決於事件是否會發生。promise

若是是業務邏輯不復雜還好說,但是若是業務邏輯很複雜的話,回調嵌套的不少,代碼書寫起來會變得很複雜很難看懂。
還有一個問題是,若是有多個異步操做,那麼就存在一個處理順序的問題,代碼如何按照但願的順序執行。異步

Promise

簡介

Promise是抽象異步處理對象以及對其進行各類操做的組件。Promise並非從js裏出現的概念。
Promise則是把相似的異步處理對象和處理規則進行規範化, 並按照採用統一的接口來編寫,而採起規定方法以外的寫法都會出錯。函數

首先說,Promise是一個對象,因此說這個對象與js裏的其餘對象沒什麼不同的。要說不同凡響的地方時,Promise對象充當代理的做用,充當異步操做和回調函數之間的中介學習

Promise的思想是:每次執行一個異步操做之後,馬上返回一個Promise對象,由於是馬上操做,因此咱們能夠進行同步操做流程。這個Promise對象有一個then方法,指定回調函數,用於在異步操做執行完後執行回調函數處理。線程

//換成Promise的寫法
new Promise(f5).then(f4).then(f3).then(f2).then(f1)

使用Promise,用同步的寫法處理異步操做的代碼,使得代碼清晰易懂,等一個異步函數處理完成以後,纔會執行下一個then裏邊的函數。這樣就避免了前邊的多個回調可能引起的順序問題。代理

Promise接口

前邊說過,Promise接口的做用是,返回一個Promise對象。
一個Promise對象有三種狀態code

  • pending 異步操做未完成對象

  • resolve 異步操做已成功完成

  • reject 異步操做失敗

至於這三種關係的途徑能夠描述爲兩種

pending ---> resolve
pending ---> reject

這種變化只會出現一次。因此,意思是,一個異步操做結束以後只會有兩種狀態,成功or失敗。異步操做成功時,Promise對象返回一個值,對象狀態變爲resolve,異步操做失敗時,對象狀態變爲reject。

Promise對象用then方法添加回調函數,then方法支持鏈式調用。

promise.then(onFulfilled, onRejected)

then方法接受兩個參數,看名字就知道第一個參數是Promise對象狀態時resolve的時候調用,而第二個參數能夠省略,表示Promise調用失敗狀態是reject的時候執行這個回調。

除了then方法,還有一個專門處理異常的方法.
.catch 也能夠理解爲 promise.then(undefined, onRejected) 。

promise.catch(onRejected)

then和catch兩個方法是寫到了Promise對象的原型上的,每一個Promise對象均可以調用。

Promise對象的生成

ES6提供了原生的Promise對象構造函數,用於生成Promise對象,

var promise = new Promise(function(resolve, reject){
  // 異步操做的代碼

  if (/* 異步操做成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

Promise對象接收一個函數做爲構造函數的參數,這個函數一樣有兩個參數,這兩個參數是由js引擎提供的函數,不用本身來部署。
resolve函數的做用是把Promise對象的狀態從pending變爲resolve,在異步操做成功的時候調用,而且將異步操做的結果做爲參數傳過去。一樣的,reject函數的做用是把對象狀態從pending變成reject,在失敗的時候調用,而且傳遞結果參數。

接下來,當Promise對象建立成功以後就能夠用then方法鏈式調用了。

Promise對象其餘方法

1.Promise.resolve()

通常狀況下,咱們會用構造函數的方法建立Promise對象。可是,除此以外咱們也會有其餘方法建立。
靜態方法Promise.resolve(value)被認爲是new Promise方式建立Promise對象的快捷方式。

Promise.resolve(42).then(function(value){
    console.log(value);
})

resolve()會讓對象狀態當即變成resolved,而且將形參馬上傳給下一個回調。

2.Promise.reject()

這個方法相似上一個方法,也是建立Promise對象的快捷方式,可是隻會把Promise對象從pending變爲rejected。參數是一個異常對象,傳遞給下一個catch方法或者then方法。

Promise.reject(new Error("BOOM!")).catch(function(error){
    console.error(error);
});
3.Promise.all() && Promise.race()

到目前爲止,已經學習了建立Promise對象和用then,catch方法來註冊回調函數。若是隻有一個Promise對象的話很好說,可是若是有多個Promise對象的時候要如何處理呢。

Promise.all 接收一個 promise對象的數組做爲參數,當這個數組裏的全部promise對象所有變爲resolve或reject狀態的時候,它纔會去調用 .then 方法。

Promise.race 只要有一個promise對象進入 FulFilled 或者 Rejected 狀態的話,就會繼續進行後面的處理。

4. 每次調用then都會返回一個新建立的promise對象
function f1(v){
    console.log(v);
    return 2;
}
function f2(v){
    console.log(v)
}
Promise.resolve(1).then(f1).then(f2);
相關文章
相關標籤/搜索