PWA(Progressive Web App)入门系列:(四)Promise
前言
這一章說一下ES6的Promise對象。為什么要在PWA系列的文章中講Promise呢?因為PWA中的許多技術API中都是以Promise返回的方式返回的,為了對后續章節中PWA技術API更好的理解,這里就來說一個Promise對象。
Promise出現的背景
在JavaScript當中,處理異步操作時,我們需要知道操作是否已經完成,當執行完成的時候會返回一個回調函數,表示操作已經完成。所以在處理異步操作時,通常是使用回調嵌套的方式(CallBack)。但是如果出現多層回調嵌套,也就是我們常說的回調金字塔(Pyramid of Doom),絕對是一種糟糕的編程體驗。
像這樣:
function a1() {function a2() {function a3() {function a4() {function a5() {...}}}} }回調方式主要會導致兩個關鍵問題:
在這種情況下,Promise 對象出現了。2015 年 6 月,加入了ECMAScript 6 的標準。
Promise簡介
Promise 對象用于一個異步操作的最終完成(或失敗)及其結果值的表示。一個 Promise 對象代表一個目前還不可用,但是在未來的某個時間點可以被解析的值。它允許你以一種同步的方式編寫異步代碼。Promises 將嵌套的回調改造成一系列的.then的鏈式調用,去除了層層嵌套的劣式代碼風格。Promises 不是一種解決具體問題的算法,而已一種更好的代碼組織模式。
上面的代碼,用Promise的方式可以寫成:
a1.then(function(data) {return a2(data) }) .then(function(data) {return a3(data) }) .then(function(data) {return a4(data) }) .then(function(data) {return a5(data) }) ...Promise 對象有以下兩個特點:
Promise狀態:
語法
new Promise( function(resolve, reject) {...} /* executor */ );executor是一個帶有 resolve 和 reject 兩個參數的函數 。executor 函數在Promise構造函數執行時同步執行,被傳遞 resolve 和 reject 函數(executor 函數在Promise構造函數返回新建對象前被調用)。resolve 和 reject 函數被調用時,分別將promise的狀態改為fulfilled(完成)或rejected(失敗)。executor 內部通常會執行一些異步操作,一旦完成,可以調用resolve函數來將promise狀態改成fulfilled,或者在發生錯誤時將它的狀態改為rejected。
如果在executor函數中拋出一個錯誤,那么該promise 狀態為rejected。executor函數的返回值被忽略。
基本用法
new Promise(function(resolve, reject) {// ... some codeif (/* 操作成功 */){resolve(value);} else {reject(error);} });注意:實例化的Promise對象會立即執行
方法
下面說一下Promise對象的方法。
Promise.prototype.then()
then方法是定義在原型對象Promise.prototype上的。它最多需要有兩個參數:Promise 的成功和失敗情況的回調函數。then方法的第一個參數是resolved狀態的回調函數,第二個參數(可選)是rejected狀態的回調函數。
then方法返回的是一個新的Promise實例。因此可以采用鏈式寫法,即then方法后面再調用另一個then方法。
Promise.prototype.catch()
catch() 方法返回一個Promise,只處理拒絕的情況。它的行為與調用Promise.prototype.then(undefined, onRejected) 相同。用于指定發生錯誤時的回調函數。
taskkA() .then(function() {return taskB() }) .then(function() {return taskC() }) .catch(function(err) {// ... }) .then(function() {return taskD() })Promise.resolve()
返回一個狀態由給定value決定的Promise對象。如果該值是一個Promise對象,則直接返回該對象;如果該值是thenable(即,帶有then方法的對象),返回的Promise對象的最終狀態由then方法執行決定;否則的話(該value為空,基本類型或者不帶then方法的對象),返回的Promise對象狀態為fulfilled,并且將該value傳遞給對應的then方法。通常而言,如果你不知道一個值是否是Promise對象,使用Promise.resolve(value) 來返回一個Promise對象,這樣就能將該value以Promise對象形式使用。
Promise.resolve(value) Promise.resolve(promise) Promise.resolve(thenable)有時需要將現有對象轉為 Promise 對象,Promise.resolve方法就起到這個作用。
Promise.resolve('data') // 等價于 new Promise(resolve => resolve('data'))Promise.reject()
返回一個狀態為失敗的Promise對象,并將給定的失敗信息傳遞給對應的處理方法。該實例的狀態為rejected。
var p = Promise.reject('出錯了'); // 等同于 var p = new Promise((resolve, reject) => reject('出錯了'))p.catch(function(err) {console.log(err) }) // 出錯了Promise.all()
這個方法返回一個新的promise對象,該promise對象在iterable參數對象里所有的promise對象都成功的時候才會觸發成功,一旦有任何一個iterable里面的promise對象失敗則立即觸發該promise對象的失敗。這個新的promise對象在觸發成功狀態以后,會把一個包含iterable里所有promise返回值的數組作為成功回調的返回值,順序跟iterable的順序保持一致;如果這個新的promise對象觸發了失敗狀態,它會把iterable里第一個觸發失敗的promise對象的錯誤信息作為它的失敗錯誤信息。Promise.all方法常被用于處理多個promise對象的狀態集合。
Promise.all(iterable)iterable: 一個可迭代對象,例如一個 Array 或 String。
上述可迭代對象中的所有 Promise 被 resolve 之后返回 resolve,或者在任一 Promise 被 reject 后返回 reject。
Promise.race()
當iterable參數里的任意一個子promise被成功或失敗后,父promise馬上也會用子promise的成功返回值或失敗詳情作為參數調用父promise綁定的相應句柄,并返回該promise對象。
用法和Promise.all()類似。
Promise.race(iterable);基本應用
下面根據Promise的特性,做幾個例子。
異步加載圖片
function loadImage(url) {return new Promise(function(resolve, reject) {var img= new Image();img.onload = function() {resolve(img);};img.onerror = function(err) {reject(new Error(err));};img.src = url;}); }網絡請求超時處理
Promise.race([fetch('http://xxxx.xxx'),new Promise(function (resolve, reject) {setTimeout(() => reject(new Error('請求超時')), 6000)}) ]). then(function(data) {// ... }) .catch(function(err) {// 處理錯誤... })總結
這一篇里,對Promise的背景由來,及相關方法進行了相應的介紹說明,也了解到了Promise在異步處理上的使用優勢。
博客名稱:王樂平博客
CSDN博客地址:http://blog.csdn.net/lecepin
本作品采用知識共享署名-非商業性使用-禁止演繹 4.0 國際許可協議進行許可。總結
以上是生活随笔為你收集整理的PWA(Progressive Web App)入门系列:(四)Promise的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 485接口原理
- 下一篇: 静态库和动态库的分析