這篇將結合自身使用ES6 Promise的情況,總結下Promise在我們專案開發中的常見的應用場景,當然,Promise 也許不是唯一選項,但是我們作為一個合格的前端開發人員,我們有必要了解它。
Promise.all
#語法:Promise.all(iterable)
參數:一個可迭代對象,如Array。
傳回值:
如果傳遞的iterable為空,則是已經解決的Promise。
Promise.all([]).then(res=>{ console.log(res)//[] })
非異步解析的Promise(如果傳遞的Iterable不包含Promise)。請注意,在這種情況下,Google Chrome 58返回已解決的承諾。
Promise.all([1,2,3]).then(res=>{ console.log(res)//[1,2,3] })
-
當給定可迭代物件中的所有promise已解決,或任何promise均被拒絕時,此傳回的promise將被非同步解析/拒絕(堆疊為空白時)
1. 當給定可迭代物件中的所有promise 已解決
let promise1 = new Promise((resolve,reject)=>{ resolve(1) }) let promise2 = new Promise((resolve,reject)=>{ resolve(2) }) Promise.all([promise1,promise2,3]).then(res=>{ console.log(res)//[1,2,3] })
2..當給予可迭代物件中的任何promise被拒絕時
let promise1 = new Promise((resolve,reject)=>{ resolve(1) }) let promise2 = new Promise((resolve,reject)=>{ reject(2) }) Promise.all([promise1,promise2,3]).then(res=>{ console.log(res) }).catch(err=>{ console.log(err)//2 })
描述:
此方法對於匯總多個promise的結果很有用, 在ES6中可以將多個Promise.all非同步請求並行操作:
1.當所有結果成功返回時按照請求順序返回成功;
2.當其中有一個失敗方法時,則進入失敗方法;
##應用場景1 :多個請求結果合併在一起
具體描述:一個頁面,有多個請求,我們需求所有的請求都返回資料後再一起處理渲染#思考:如果並發請求的話,每個請求的loading狀態要單獨設置,多個的話可能多個loading 重合,頁面顯示的內容根據請求返回數據的快慢有所差異,具體表現在渲染的過程,為提升使用者體驗,我們可以採用所有請求返回資料後,再一起渲染,此時我們關閉請求的單獨loading設置,透過Promise.all 匯總請求結果,從開始到結束,我們只設置一個loading 即可。
//1.获取轮播数据列表 function getBannerList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('轮播数据') },300) }) } //2.获取店铺列表 function getStoreList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('店铺数据') },500) }) } //3.获取分类列表 function getCategoryList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('分类数据') },700) }) } function initLoad(){ // loading.show() //加载loading Promise.all([getBannerList(),getStoreList(),getCategoryList()]).then(res=>{ console.log(res) // loading.hide() //关闭loading }).catch(err=>{ console.log(err) // loading.hide()//关闭loading }) } //数据初始化 initLoad()
應用程式場景2:合併請求結果並處理錯誤
描述:我們需求單獨處理一個請求的資料渲染和錯誤處理邏輯,有多個請求,我們就需要在多個地方寫思考:我們能否把多個請求合併在一起,哪怕有的請求失敗了,也返回給我們,我們只需要在一個地方處理這些數據和錯誤的邏輯即可。
//1.获取轮播图数据列表 function getBannerList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ // resolve('轮播图数据') reject('获取轮播图数据失败啦') },300) }) } //2.获取店铺列表 function getStoreList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('店铺数据') },500) }) } //3.获取分类列表 function getCategoryList(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve('分类数据') },700) }) } function initLoad(){ // loading.show() Promise.all([ getBannerList().catch(err=>err), getStoreList().catch(err=>err), getCategoryList().catch(err=>err) ]).then(res=>{ console.log(res) // ["获取轮播图数据失败啦", "店铺数据", "分类数据"] if(res[0] == '轮播图数据'){ //渲染 }else{ //获取 轮播图数据 失败的逻辑 } if(res[1] == '店铺数据'){ //渲染 }else{ //获取 店铺列表数据 失败的逻辑 } if(res[2] == '分类数据'){ //渲染 }else{ //获取 分类列表数据 失败的逻辑 } // loading.hide() }) } initLoad()
有時候頁面掛掉了,可能因為介面異常導致,或許只是一個無關緊要的介面掛掉了。那麼一個介面掛掉了為什麼會導致整個頁面無資料呢? Promise.all告訴我們,如果參數中promise 有一個失敗(rejected),此實例回呼失敗(reject),就不再執行then方法回調,以上用例正好可以解決此種問題
應用場景3:驗證多個請求結果是否都是滿足條件
描述:在一個微信小程式專案中,做一個表單的輸入內容安全驗證,呼叫的是雲函數寫的方法,表單有多7個欄位需要驗證,都是呼叫的一個內容安全校驗接口,全部驗證通過則可以進行正常的提交function verify1(content){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve(true) },200) }) } function verify2(content){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve(true) },700) }) } function verify3(content){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve(true) },300) }) } Promise.all([verify1('校验字段1的内容'),verify2('校验字段2的内容'),verify3('校验字段3的内容')]).then(result=>{ console.log(result)//[true, true, true] let verifyResult = result.every(item=>item) //验证结果 console.log(verifyResult?'通过验证':'未通过验证')// 通过验证 }).catch(err=>{ console.log(err) })
Promise .race
語法:Promise.race(iterable)
參數: iterable 可迭代的對象,例如Array 。可迭代的。
傳回值:Promise.race(iterable) 方法傳回一個promise,一旦迭代器中的某個promise解決或拒絕,傳回的promise就會解決或拒絕
描述race 函數傳回一個Promise,它將與第一個傳遞的promise 相同的完成方式完成。它可以是完成( resolves),也可以是失敗(rejects),這取決於第一個完成的方式是兩個中的哪一個。
如果傳的迭代是空的,則傳回的 promise 將永遠等待。 如果迭代包含一個或多個非承諾值和/或已解決/拒絕的承諾,則 Promise.race 將解析為迭代中找到的第一個值。應用程式場景1:圖片請求逾時
//请求某个图片资源 function requestImg(){ var p = new Promise(function(resolve, reject){ var img = new Image(); img.onload = function(){ resolve(img); } //img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg"; 正确的 img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg1"; }); return p; } //延时函数,用于给请求计时 function timeout(){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ reject('图片请求超时'); }, 5000); }); return p; } Promise .race([requestImg(), timeout()]) .then(function(results){ console.log(results); }) .catch(function(reason){ console.log(reason); });
#應用程式場景2:請求逾時提示
描述:有些時候,我們前一秒刷著新聞,下一秒進入電梯後,手機頁面上就會提示你「網路不佳」//请求 function request(){ return new Promise(function(resolve, reject){ setTimeout(()=>{ resolve('请求成功') },4000) }) } //请求超时提醒 function timeout(){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ reject('网络不佳'); }, 3000); }); return p; } Promise.race([ request(), timeout() ]) .then(res=>{ console.log(res) }).catch(err=>{ console.log(err)//网络不佳 })
Promise.prototype.then
應用程式場景1:下個請求依賴上個請求的結果#
描述:类似微信小程序的登录,首先需要 执行微信小程序的 登录 wx.login 返回了code,然后调用后端写的登录接口,传入 code ,然后返回 token ,然后每次的请求都必须携带 token,即下一次的请求依赖上一次请求返回的数据
function A(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('B依赖的数据') },300) }) } function B(prams){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(prams + 'C依赖的数据') },500) }) } function C(prams){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(prams) },1000) }) } //我们期望的是走 try ,由于A B C模拟的请求中都是没有reject,用 try catch 捕获错误 try{ A().then( res=>B(res) ).then( res=>C(res) ).then( res=>{ console.log(res)//B依赖的数据C依赖的数据 }) } catch(e){ }
应用场景2:中间件功能使用
描述:接口返回的数据量比较大,在一个then 里面处理 显得臃肿,多个渲染数据分别给个then,让其各司其职
//模拟后端返回的数据 let result = { bannerList:[ {img:'轮播图地址'} //... ], storeList:[ {name:'店铺列表'} //... ], categoryList:[ {name:'分类列表'} //... ], //... } function getInfo(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(result) },500) }) } getInfo().then(res=>{ let { bannerList } = res //渲染轮播图 console.log(bannerList) return res }).then(res=>{ let { storeList } = res //渲染店铺列表 console.log(storeList) return res }).then(res=>{ let { categoryList } = res console.log(categoryList) //渲染分类列表 return res })
推荐教程:《JS教程》
以上是前端 Promise 常見的一些應用場景的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

記事本++7.3.1
好用且免費的程式碼編輯器

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),