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