我們知道,在promise對象的then方法可以處理onfulfilled和onrejected兩個事件監(jiān)聽回調(diào),但是我們一般采用catch來處理onrejected的監(jiān)聽回調(diào),因為catch可以捕獲部分程序異常;有利于程序的健壯性。例如:
- function getBanner() {
- let p = new Promise((resolve, reject) => {
- $.ajax({
- type: "GET",
- url: "http://localhost:3000/api/index/banner",
- success: function (response) {
- resolve(response);
- },
- error: function (err) {
- reject(err);
- }
- });
- });
- return p;
- }
- let p = getBanner()
- .then(rst => {
- return rst;
- })
- .catch(err => {
- console.log(err);
- });
我們通過jQuery的ajax來向服務器發(fā)起輪播圖數(shù)據(jù)的請求,上面代碼若是正確的執(zhí)行則會進入then方法里處理,若是異常的,也就是說必然進入catch環(huán)節(jié),這代碼看起來并沒有什么,好像也并不復雜。
但是,如果在異步請求過程中出現(xiàn)了幾個請求直接有依賴關系,則使用這種解決方案就復雜得多了。例如:
- $.ajax({
- url: "http://www.ujiuye.tech/:3000/api/firstCategory", // 所有一級分類
- dataType: "json",
- success(res) {
- $.ajax({
- url: `http://www.ujiuye.tech/:3000/api/secondCategory`, // 傳遞一級ID換取下屬的二級分類列表
- data: {
- firstId: res['list'][0][0]['firstId']
- },
- dataType: "json",
- success(res2) {
- $.ajax({
- url: `http://www.ujiuye.tech/:3000/api/thiredCategory`, // 傳遞二級分類ID, 獲取下屬的三級分類列表
- data: {
- secondId: res2['list'][0]['secondId']
- },
- dataType: "json",
- success(res3) {
- $.ajax({
- url: `http://www.ujiuye.tech/:3000/api/categoryList`,// 傳遞三級分類ID, 獲取下屬的商品數(shù)據(jù)列表
- data: {
- thiredId: res3['list'][0]['thiredId']
- },
- dataType: "json",
- success(result) {
- console.log(result);
- }
- })
- }
- })
- }
- })
- }
- })
在小U商城項目中的商品列表頁面,我們同時要發(fā)起四個請求來分別獲。阂患壏诸、二級分類、三級分類和商品,那么這是時候利用回調(diào)函數(shù)會出現(xiàn)”回調(diào)地獄”的現(xiàn)象,即使是使用promise來優(yōu)化,也會出現(xiàn)大量的代碼嵌套,這樣的代碼會容易讓人疑惑,而且也不利于后續(xù)的開發(fā)維護。所以我們可以使用async...await來優(yōu)化這些。
例如上面請求輪播圖的例子,使用async和await來優(yōu)化之后:
- function getBanner() {
- let p = new Promise((resolve, reject) => {
- $.ajax({
- type: "GET",
- url: "http://localhost:3000/api/index/banner",
- success: function (response) {
- resolve(response);
- },
- error: function (err) {
- reject(err);
- }
- });
- });
- return p;
- }
- async function getData(){
- let data=await getBanner();
- console.log(data);
- }
這樣的代碼相比于上面的代碼要簡化很多,但是也有弊端,由于await只能接收promise的成功結果,也就是說,若上面代碼出現(xiàn)了異常,則代碼會中斷執(zhí)行。作為一個優(yōu)秀的開發(fā)人員肯定不希望代碼崩掉,那么該如何解決異常呢,有兩種方案:一是采用try..catch來捕獲異常,另外是使用catch
- async function getData() {
- try {
- let data = await getBanner();
- console.log(data);
- } catch (e) {
- console.log(e);
- }
- }
- //或者
- async function getData() {
- let data = await getBanner().catch(e => {
- console.log(e);
- })
- console.log(data);
- }
但這兩種方案都又會出現(xiàn)嵌套,特別是若發(fā)起一些負責的請求(例如上面回調(diào)地獄的情況),則代碼依然非常復雜,那么有沒有更好的解決方案呢。答案是有。在項目開發(fā)過程中,我們經(jīng)常使用await-to-js的技術來解決這個問題:
- function to(p) {
- return p
- .then(data => [null, data])
- .catch(err => [err, null]);
- }
其實這個方案依然是利用promise的鏈式調(diào)用原理來解決的。那么使用,最后代碼為:
- function to(p) {
- return p
- .then(data => [null, data])
- .catch(err => [err, null]);
- }
- async function getData() {
- let [err, data] = await to(getBanner())
- }
利用這個方案,大家發(fā)現(xiàn),代碼量不僅大大的減少,而且兼容性更加友好。
更多內(nèi)容
>>本文地址:http://nfbqydst.cn/zhuanye/2021/70198.html
聲明:本站稿件版權均屬中公教育優(yōu)就業(yè)所有,未經(jīng)許可不得擅自轉載。
1 您的年齡
2 您的學歷
3 您更想做哪個方向的工作?