1. 程式人生 > >ES6入門之Promise物件

ES6入門之Promise物件

1. Promise 的含義

Promise 是非同步程式設計的一種解決方案,比傳統的解決方案--回撥函式和事件更合理、更強大。

1.1 什麼是Promise

簡單來說就是一個容器,裡面儲存著某個未來才會結束的事件(也就是非同步操作)的結果。從語法上來講,Promise是一個物件,從它可以獲取非同步操作的訊息,它提供統一的API,各種非同步操作都可以用同樣的方法進行處理。

Promise有兩個特點:

1.1.1、物件的狀態不受外界影響。Promise物件代表一個非同步操作,有三種狀態:pending(進行中)、fulfilled(已成功)和 rejected(已失敗)。只有非同步操作的結果,可以決定當前是哪一種狀態、任何其他操作都無法改版這個狀態。

1.1.2、一旦狀態改版,就不會再變,任何時候都可以得到這個結果。Promise物件的狀態改變,只存在兩種可能:從 pending 變為 fulfilled 和 從 pending 變為 rejeced。只要這兩種情況發生,狀態就終止,不會再變了並一直保持這個結果。這時就稱為 resolved(已定型)。如果改版已經發生了,即使再對Promise物件添加回調函式,也會立即得到這個結果。如果你錯過了再想去監聽,是得不到結果的。

1.1.3、有了Promise物件,就可以將非同步操作以同步操作的流程顯示出來,這樣就避免了層層巢狀的回撥函式。Promise物件提供統一的介面,使得控制非同步操作更加容易。

1.1.4、Promise也有一些缺點,就是無法取消 Promise,一旦建立就會立即執行,無法中途取消。如果不設定回撥函式,Promise內部丟擲的錯誤不會反應到外部。另外如果處於 pending 狀態時,是無法知道現在到了哪一個階段。

2. 基本用法

Promise物件是一個建構函式,用來生成Promise例項

const promise = new Promise((reolve, reject) => {
    if (// 非同步操作成功) {
        resolve(val)
    }else{
        reject(val)
    }
})

Promise 建構函式接受一個函式作為引數,該函式的兩個引數分別是 resolve 和 reject。

resolve:,將Promise物件的狀態從『未完成』變為『成功』(pending => resolved),在非同步操作成功時呼叫,並將非同步操作的結果作為引數傳遞出去。

reject:將Promise物件的狀態從『未完成』變為『失敗』(pending => rejected),在非同步操作失敗時呼叫,並將非同步操作的結果作為引數傳遞出去。

Promise 例項生成以後,可以用 then 方法分別指定 resolved 狀態和 rejected 狀態的回撥函式。

promise.then((val) => {
    // success
},(err) => {
    // failure
})

then方法可以接受兩個回撥函式作為引數。(第二個函式可選,這兩個函式都接受Promise物件傳出的值作為引數)

1、第一個回撥函式在Promise物件的狀態變為『resolved』時呼叫。

2、第二個回撥函式在Promise物件的狀態變為『rejected』時呼叫。

例項:

function timeout(ms) {
    retrun new Promise((resolve, reject) => {
        setTimeout(resolve, ms, 'done')
    })
}

timeout(100)
.then((v) => {
    console.log(v)
})

上面程式碼中,timeout方法返回一個Promise例項,表示一段時間以後才會發生的結果,過了 ms時間後,Promise狀態變為『resolved』然後就會觸發then方法繫結的回撥函式。

Promise 建立後就會立即執行

let promise = new Promise((resolve, reject) => {
    console.log('Promise')
    resolve()
})

promise
.then(() => {
    console.log('resolved')
})

console.log('hh')

// Promise
// hh
// resolved

Promise建立後立即執行,首先輸出 「Promise」然後執行promise 的then函式,然後首先執行同步任務 輸出 hh 在執行 then方法的回撥函式輸出resolved

如果呼叫 resolve 函式和 reject 函式時帶有引數,那麼它們的引數會被傳遞給回撥函式。reject函式的引數通常是Error物件的例項,表示丟擲的錯誤。resolve函式的引數除了正常的值以外,還有可能是一個Promise例項。resolve實在成功的時候呼叫,reject是在失敗的時候呼叫。

const p1 = new Promise(function (resolve, reject) {
  // ...
});

const p2 = new Promise(function (resolve, reject) {
  // ...
  resolve(p1);
})

上述程式碼中:p1 和 p2都是Promise的例項,但是p2的 resolve方法將 p1作為引數,即一個非同步操作的結果返回是另一個非同步操作。

注意:p1的狀態就會傳遞給p2,p1的狀態決定了p2的狀態。如果p1的狀態是pending,那麼p2的回撥函式就會等待p1的狀態改變;如果p1的狀態已經是 resolved 或者 rejected,那麼p2的回撥函式會立即執行。

一般來說,呼叫resolve 或 reject以後,Promise的程序就就結束了,後續操作應該放到 then方法裡,而不是直接寫在 resolve 或 reject 的後面。另外最後在它們之前加上 return語句。

3. Promise.prototype.then()

Promise例項具有 then 方法,then方法是定義在原型物件 Promise.prototype上的。它的作用是為 Promise 例項新增狀態改變時的回撥函式。then 的第一個引數是 resolved狀態的回撥函式,第二個引數是 rejected狀態的回撥函式。

then方法返回的是一個新的 Promise 例項,不是原來那個,因此可以使用鏈式寫法。.then().then()

a().then((j) => {
    retrun j
}).then((i) => {
    console.log(i)
},(err)=>{
    console.log(err)
})

上面 第一個then方法指定的回撥函式,返回的是另一個 Promise 物件。這時,第二個 then 方法指定的回撥函式,就會等這個新的 Promise物件狀態發生變化,如果變為 resolved,就呼叫第一個回撥函式,如果狀態變為 rejected,就呼叫第二個回撥函式。

4. Promise.prototype.catch()

Promise.prototype.catch 方法是 .then(null, rejecton) 或 .then(undefined, rejection)的別名,用於指定發生錯誤時的回撥函式。

a().then((p) => {
    // success
}).catch((err) => {
    console.log('err')
})

如果物件的狀態變為 resolved, 則會呼叫 then 方法指定的回撥函式 success,如果非同步操作丟擲錯誤,狀態就會變為 rejected,就會呼叫 catch 方法指定的回撥函式處理這個錯誤。如果 then 方法指定的回撥函式,在執行中丟擲錯誤,也會被catch 方法捕獲。

另外reject方法的作用等同於丟擲錯誤

如果 Promise狀態已經變成 resolved,再丟擲錯誤是無效的。因為狀態一旦改版,就永遠保持,不會再變了。 而且Promise的錯誤有『冒泡』的性質,會一直向後傳遞,直到被捕獲位置,它的錯誤總會被下一個catch語句捕獲。

建議:Promise 物件後面要跟catch方法,這樣可以處理 Promise 內部發生的錯誤。catch方法返回的還是一個 Promise 物件,因此後面還可以接著呼叫then方法。

注意: catch函式中的方法發生錯誤,如果後面沒有別的catch 方法,那麼錯誤將不會被捕獲,如果 catch 後面 還有catch ,第二個catch將會捕獲前一個catch方法丟擲的錯誤。

5. Promise.prototype.finally()

finally 方法用於指定不管 Promise 物件最後狀態如何,都會執行的操作。

promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

以上,不管promise 最後的狀態,都會執行 finally 方法指定的函式。

finally 方法的回撥函式不接受任何引數,所以就無法知道之前Promise狀態到底是 fulfilled 還是 rejected。所以在finally方法裡面的操作,是與之前狀態無關的而且不依賴於Promise的執行結果。

6. Promise.all()

Promise.all 方法用於將多個 Promise 例項,包裝成一個新的 Promise例項。

const p = Promise.all([p1, p2, p3])

Promise.all 方法接受一個數組作為引數,p1、p2、p3都是Promise例項,如果不是,就會先呼叫Promise.resolve方法,將引數轉為 Promise 例項再處理。(Promise.all 方法的引數可以不是陣列,但必須具有 Iterator 介面,且返回的每個成員都是 Promise 例項。)

Promise.all 的狀態有兩種情況:

1、如果 p1 p2 p3的狀態都變成了 fulfilled,p的狀態才是fulfilled,這時候返回一個 p1 p2 p3返回值組成的陣列,傳遞給 p 的回撥函式。

2、如果 p1 p2 p3中任一一個被rejected,p 的狀態就變成了 rejected,這時候返回的是第一個被 rejected 例項的返回值,傳遞給 p 的回撥函式。

注意,如果作為引數的 Promise 例項,自己定義了catch方法,那麼它一旦被rejected,並不會觸發Promise.all()的catch方法。而是觸發自己定義的catch方法。

7. Promise.race()

Promise.race方法同樣是將多個 Promise 例項,包裝成一個新的 Promise例項。

const p = Promise.race([p1, p2, p3]);

與 Promise.all 的區別就是 p1 p2 p3 中一個例項改變狀態,那麼 p 的狀態就跟著改變了,返回值為最先返回那個Promise例項的返回值。

8. Promise.resolve()

將現有物件轉為 Promise 物件。

1、如果引數是一個Promise 例項
那麼將不做任何修改。
2、引數是一個 thenable物件(具有then方法的物件)
將這個物件轉為Promise物件,然後立即執行 thenable物件的then方法
3、引數不是具有then方法的物件,或根本不是物件
返回一個新的Promise物件,狀態為 resolved
4、不帶任何引數
直接返回一個 resolved 狀態的Promise物件

9. Promise.reject()

Promise.reject(reason)方法也會返回一個新的 Promise 例項,該例項的狀態為rejected。回撥函式立即執行。

關注公眾號 【小夭同學】

相關推薦

ES6入門Promise物件

1. Promise 的含義 Promise 是非同步程式設計的一種解決方案,比傳統的解決方案--回撥函式和事件更合理、更強大。 1.1 什麼是Promise 簡單來說就是一個容器,裡面儲存著某個未來才會結束的事件(也就是非同步操作)的結果。從語法上來講,Promise是一個物件,從它可以獲取非同步

ES6Promise物件

首先,文章內容基本來自ECMAScript 6 入門(作者 阮一峰) 簡介 Promise物件是非同步程式設計的一種解決方案。所謂Promise,簡單來說就是一種容器,裡面包含著未來可能結束的一個事件的結果。 Promise包含三種狀態,pending,f

ES6Promise 物件

含義 Promise是非同步程式設計的一種解決方案,比回撥函式和事件這兩個傳統的解決方案更合理更強大。 是一個容器,存放著某個未來才會結束的事件(通常是一個非同步操作)結果。從語義上說,Promise是一個物件,可以獲取非同步操作的資訊。提供統一的API,各種非同步操作都可以同樣

ES6Promise物件學習——8個例子學會Promise

目錄 Promise 立即執行 Promise 三種狀態 Promise 不可逆性 鏈式呼叫 Promise.then()回撥非同步性 Promise中的異常 Promise.resolve() resolve vs reject 一、Promise

原生es6封裝一個Promise物件

實現功能: 已實現 Promise 基本功能,與原生一樣,非同步、同步操作均ok,具體包括: MyPromise.prototype.then() MyPromise.prototype.catch() 與原生 Promise 略有出入 MyPromise.protot

ES6中的Promise物件

什麼是 Promise : 簡單說Promise 就是一個容器,裡面儲存著某個未來才會結束的事件(通常是一個非同步操作)的結果. 從語法上說,Promise是一個物件,從他可以獲取非同步操作的訊息. Promise 是非同步程式設計的一種解決方案,比傳統的解決方

JavaScriptPromise物件

Promise 是非同步程式設計的一種解決方案,比傳統的解決方案——回撥函式和事件——更合理和更強大。它由社群最早提出和實現,ES6 將其寫進了語言標準,統一了用法,原生提供了 Promise 物件。 Promise 物件是一個代理物件(代理一個值),被代理

ES6學習面向物件

1.寫法 class User{ constructor(name,password){//構造器 this.name = name; this.password = password;

Scala光速入門面向物件(二)

1、函式定義 class Person{ //沒有private的var會自動生成setter和getter方法,val只有getter方法, //private定義的變數則不生成getter和setter方法 var name = "Spark"         def

ES6特性Promise總結

Promise是ES6新特性中知名度非常高的點,我實力不濟寫的不會很好,如果看官想深入學習Promise請移步其他比較權威的著作,比如阮一峰老師的《ES6入門標準》、《JavaScript Promise迷你書(中文版)》或者直接看"promise/A+"標準也行。我這篇文章的目的只是為我自己備

ES6中的Promise物件小結

Promise是一種非同步程式設計的解決方案,ES6提供原生的Promise,它比傳統的解決方案,回撥函式和事件,更加合理和強大。 Promise物件有以下兩個特點: 1、物件的狀態不受外界影響。Promise物件代表一個非同步操作,有三種狀態:pendin

es6學習Promise

一.含義 Promise是JavaScript的一種非同步解決方案,具有3中狀態(pending進行中,fulfilled已經成功,rejected已失敗). 二.Promise的使用 1.Promise帶有resolve(成功),reject(失敗)兩個

.Net Remoting 技術入門遠端物件啟用模式

遠端物件啟用模式是指分別在伺服器和客戶端如何建立遠端物件,主要分為伺服器啟用和客戶端啟用一、伺服器端啟用    1、服務端:使用 RemotingConfiguration類的靜態函式RegisterWellKnownS

ES6入門let和const命令

前言 大家好,我是一隻流浪的kk,當你看到這邊部落格的時候,說明你已經進入了ES6學習的領域了,從本篇部落格開始,我將會將自己學習到ES6的相關知識進行整理,方便大家參考和學習,那麼我將帶你進入第一節的內容學習let和const命令,本篇部落格從三個方面進行全方位解析。 let命令 首先我們需要學習的是

ES6入門變數的解構賦值(二)

前言 在上一章 ES6入門之let和const命令中我們對ES6的相關語法已經有了初步瞭解,上一章中我們主要學習了三大部分的內容,let命令的使用,塊級作用域,const命令的使用,那麼從本篇部落格將進一步深入瞭解ES6中的相關語法,畢竟未來ES6是主流。 本章目標  學會陣列的解構賦值

ES6 Promise物件例項方法(2)

ES6 Promise物件之例項方法(2) 上一篇關於Promise的文章介紹了Promise的基本用法,這一篇繼續上一篇,介紹Promise的各種方法: (1)Promise.prototype.then() then方法是定義在原型物件Promise.prototype上的。

JavaScript面向對象輕松入門封裝(demo by ES5、ES6、TypeScript)

get scrip 鏈式調用 class www 資料 怎麽辦 宋體 概念   本章默認大家已經看過作者的前一篇文章 《JavaScript面向對象輕松入門之抽象》 為什麽要封裝?   封裝(Encapsulation)就是把對象的內部屬性和方法隱藏起來,外部代碼訪問該對象

JavaScript面向對象輕松入門繼承(demo by ES5、ES6)

element 增加 實現 原型 面向 pro es6 dog 關鍵字   繼承是面向對象很重要的一個概念,分為接口繼承和實現繼承,接口繼承即為繼承某個對象的方法,實現繼承即為繼承某個對象的屬性。JavvaScript通過原型鏈來實現接口繼承、call()或apply()來

JavaScript面向對象輕松入門多態(demo by ES5、ES6、TypeScript)

我會 維護 type 重載 prot 鼠標 案例 類方法 最大   多態(Polymorphism)按字面的意思就是“多種狀態”,同樣的行為(方法)在不同對象上有不同的狀態。  在OOP中很多地方都要用到多態的特性,比如同樣是點擊鼠標右鍵,點擊快捷方式、點擊桌面空白處、點擊

ES6 異步編程解決方案 Promise 對象

詳解 on() 基本 ack 地獄 down 場景 fill success 一、Promise 概述 Promise 對象是 ES6 提供的原生的內置對象 Promise 是異步編程的一種解決方案(異步代碼同步化),比傳統的解決方案——回調函數和事件——更合理和更強大