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