精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

八個關于Promise高級用途的技巧

開發 前端
在js項目中,promise的使用應該是必不可少的,但我發現在同事和面試官中,很多中級以上的前端仍然堅持promiseInst.then()、promiseInst.catch()、Promise等常規用法等等。即使是 async/await 他們也只知道它但不知道為什么要使用它。

我發現很多人只知道如何常規地使用promise。

在js項目中,promise的使用應該是必不可少的,但我發現在同事和面試官中,很多中級以上的前端仍然堅持promiseInst.then()、promiseInst.catch()、Promise等常規用法等等。即使是 async/await 他們也只知道它但不知道為什么要使用它。

但實際上,Promise 有很多巧妙的高級用法,并且一些高級用法在 alova 請求策略庫內部也被廣泛使用。

現在,我將與大家分享8個高級使用技巧。希望這些技巧能夠對你有所幫助,現在,我們就開始吧。

1. Promise數組的串行執行

例如,如果你有一組接口需要串行執行,你可能首先想到使用await。

const requestAry = [() => api.request1(), () => api.request2(), () => api.request3()];
for (const requestItem of requestAry) {
  await requestItem();
}

如果使用promise,可以使用then函數串聯多個promise,實現串行執行。

const requestAry = [() => api.request1(), () => api.request2(), () => api.request3()];
const finallyPromise = requestAry.reduce(
     (currentPromise, nextRequest) => currentPromise.then(() => nextRequest()),
     Promise.resolve() // Create an initial promise for linking promises in the array
);

2. 在新的 Promise 范圍之外更改狀態

假設你有多個頁面,其功能要求在允許使用之前收集用戶信息。點擊使用某個功能之前,會彈出一個彈框進行信息收集。你會如何實施這個?

以下是不同級別前端同學的實現思路:

初級前端:我寫一個模態框,然后復制粘貼到其他頁面。效率非常高!

中級前端:這個不好維護。我們需要單獨封裝這個組件,并在需要的頁面引入!

高級前端:安裝任何密封的東西!!!把方法調用寫在所有頁面都可以調用的地方不是更好嗎?

想要了解高級前端是如何實現的,以vue3為例,看一下下面的例子。

<!-- App.vue -->
<template>
<!-- The following is the modal box component -->
   <div class="modal" v-show="visible">
     <div>
       User name: <input v-model="info.name" />
     </div>
     <!-- Other information -->
     <button @click="handleCancel">Cancel</button>
     <button @click="handleConfirm">Submit</button>
   </div>
   <!-- Page components -->
</template>
<script setup>
import { provide } from 'vue';
const visible = ref(false);
const info = reactive({
   name: ''
});
let resolveFn, rejectFn;
// Pass the information collection function to the following
provide('getInfoByModal', () => {
   visible.value = true;
   return new Promise((resolve, reject) => {
     // Assign the two functions to the outside and break through the promise scope
     resolveFn = resolve;
     rejectFn = reject;
   });
})
const handleConfirm = () => {
   resolveFn && resolveFn(info);
};
const handleCancel = () => {
   rejectFn && rejectFn(new Error('User has canceled'));
};
</script>

接下來,getInfoByModal就可以通過直接調用模態框來輕松獲取用戶填寫的數據。

<template>
   <button @click="handleClick">Fill in the information</button>
</template>




<script setup>
import { inject } from 'vue';
const getInfoByModal = inject('getInfoByModal');
const handleClick = async () => {
   // After the call, the modal box will be displayed. After the user clicks to confirm, the promise will be changed to the fullfilled state to obtain the user information.
   const info = await getInfoByModal();
   await api.submitInfo(info);
}
</script>

這也是很多UI組件庫中封裝常用組件的一種方式。

3. async/await 的替代用法

很多人只知道它是用來在調用await時接收async函數的返回值的,卻不知道async函數它實際上是一個返回promise的函數。例如,以下兩個函數是等效的:

const fn1 = async () => 1;
const fn2 = () => Promise.resolve(1);
fn1(); // Also returns a promise object with a value of 1

在大多數情況下,await 會跟隨 Promise 對象并等待它完全填充。因此,下面的 fn1 函數 wait 也是等價的:

await fn1();
const promiseInst = fn1();
await promiseInst;

然而,await也有一個鮮為人知的秘密。當它后面跟的值不是promise對象時,它會用promise對象包裝該值,所以await后面的代碼必須異步執行。例子:

Promise.resolve().then(() => {
  console.log(1);
});
await 2;
console.log(2);
//Print order bits: 1
Promise.resolve().then(() => {
  console.log(1);
});
Promise.resolve().then(() => {
  console.log(2);
});

4. 承諾實施請求共享

當一個請求已經發出但尚未得到響應時,再次發出相同的請求,就會造成請求的浪費。此時,我們可以將第一個請求的響應與第二個請求共享。

request('GET', '/test-api').then(response1 => {
  // ...
});
request('GET', '/test-api').then(response2 => {
  // ...
});
const pendingPromises = {};
function request(type, url, data) {
   // Use the request information as the only request key to cache the promise object being requested
   //Requests with the same key will reuse promise
   const requestKey = JSON.stringify([type, url, data]);
   if (pendingPromises[requestKey]) {
     return pendingPromises[requestKey];
   }
   const fetchPromise = fetch(url, {
     method: type,
     data: JSON.stringify(data)
   })
   .then(response => response.json())
   .finally(() => {
     delete pendingPromises[requestKey];
   });
   return pendingPromises[requestKey] = fetchPromise;
}

上述兩個請求實際上只發送一次,同時收到相同的響應值。

那么,請求共享有哪些使用場景呢?我認為有以下三個:

當頁面渲染多個內部組件同時獲取數據時;
提交按鈕未禁用且用戶連續多次點擊提交按鈕;
預加載數據的情況下,預加載完成之前進入預加載頁面;

這也是alova的高級功能之一。要實現請求共享,需要使用promise的緩存功能,即一個promise對象可以通過多次await獲取數據。簡單的實現思路如下:

const promise = new Promise((resolve, reject) => {
  resolve();
  reject();
});

正確答案是已滿狀態。我們只需要記住,一旦待處理的promise從一種狀態轉移到另一種狀態,就無法更改。因此,例子中是先轉為fulfilled狀態,然后reject()就不會再轉為rejected狀態。

6.徹底明確then/catch/finally返回值

一句話概括就是,上面三個函數都會返回一個新的promise包裝對象。包裝后的值是執行回調函數的返回值。如果回調函數拋出錯誤,它將包裝拒絕狀態承諾。似乎不太容易理解,我們來看一個例子:

我們可以將它們一一復制到瀏覽器控制臺并運行它們以幫助理解。

// then function
Promise.resolve().then(() => 1); // The return value is new Promise(resolve => resolve(1))
Promise.resolve().then(() => Promise.resolve(2)); // Return new Promise(resolve => resolve(Promise.resolve(2)))
Promise.resolve().then(() => {
   throw new Error('abc')
}); // Return new Promise(resolve => resolve(Promise.reject(new Error('abc'))))
Promise.reject().then(() => 1, () => 2); // The return value is new Promise(resolve => resolve(2))


//catch function
Promise.reject().catch(() => 3); // The return value is new Promise(resolve => resolve(3))
Promise.resolve().catch(() => 4); // The return value is new Promise(resolve => resolve(promise object that calls catch))
//When the finally function returns a non-promise value, return the promise object before the finally function.
Promise.resolve().finally(() => {}); // Return Promise.resolve()
Promise.reject().finally(() => {}); // Return Promise.reject()
// When the return value of the finally function is promise, wait for the returned promise to be parsed before returning the promise object before the finally function.
Promise.resolve(5).finally(() => new Promise(res => {
   setTimeout(res, 1000);
})); // Return the Promise in pending status, which will be resolved to 5 after 1 second.
Promise.reject(6).finally(() => new Promise(res => {
   setTimeout(res, 1000);
})); // Return the Promise in the pending state, and throw the number 6 after 1 second

7、then函數的第二次回調和catch回調有什么區別?

當請求發生錯誤時,會觸發 Promise 的 then 的第二個回調函數和 catch。乍一看沒有區別,但實際上前者無法捕獲then當前第一個回調函數中拋出的錯誤,但catch可以。

Promise.resolve().then(
   () => {
     throw new Error('Error from success callback');
   },
   () => {
     // will not be executed
   }
).catch(reason => {
   console.log(reason.message); // Will print out "error from success callback"
});

原理就如上一點所說的。catch 函數是在 then 函數返回的處于拒絕狀態的 Promise 上調用的,因此它的錯誤自然可以被捕獲。

8.(最終)Promise實現koa2洋蔥中間件模型

koa2框架引入了洋蔥模型,可以讓你的請求像剝洋蔥一樣一層層進去,再一層層出來,從而實現請求前后處理的統一。

我們來看一個簡單的 koa2 洋蔥模型:

const app = new Koa();
app.use(async (ctx, next) => {
  console.log('a-start');
  await next();
  console.log('a-end');
});
app.use(async (ctx, next) => {
  console.log('b-start');
  await next();
  console.log('b-end');
});




app.listen(3000);

上面的輸出是a-start -> b-start -> b-end -> a-end,這樣神奇的輸出序列是如何實現的呢?有人沒天賦,簡單的用20行左右的代碼就實現了。如有雷同,純屬巧合。

接下來我們分析一下

注:以下內容對新手不友好,請謹慎閱讀。

首先先保存中間件函數,在listen函數中收到請求后調用洋蔥模型執行。

function action(koaInstance, ctx) {
  // ...
}




class Koa {
   middlewares = [];
   use(mid) {
     this.middlewares.push(mid);
   }
   listen(port) {
     // Pseudocode simulates receiving request
     http.on('request', ctx => {
       action(this, ctx);
     });
   }
}

收到請求后,從第一個中間件開始串行執行next之前的前置邏輯。

//Start to start middleware call
function action(koaInstance, ctx) {
   let nextMiddlewareIndex = 1; // Identifies the next middleware index to be executed
   //Define next function
   function next() {
     // Before peeling the onion, calling next will call the next middleware function
     const nextMiddleware = middlewares[nextMiddlewareIndex];
     if (nextMiddleware) {
       nextMiddlewareIndex++;
       nextMiddleware(ctx, next);
     }
   }
   //Start execution from the first middleware function and pass in the ctx and next functions
   middlewares[0](ctx, next);
}

處理next之后的post邏輯

function action(koaInstance, ctx) {
   let nextMiddlewareIndex = 1;
   function next() {
     const nextMiddleware = middlewares[nextMiddlewareIndex];
     if (nextMiddleware) {
       nextMiddlewareIndex++;
       // A return is also added here to allow the execution of the middleware function to be executed in series from back to front using promises (it is recommended to understand this return repeatedly)
       return Promise.resolve(nextMiddleware(ctx, next));
     } else {
       // When the pre-logic of the last middleware is executed, return the fullyfilled promise and start executing the post-logic after next.
       return Promise.resolve();
     }
   }
   middlewares[0](ctx, next);
}

至此,一個簡單的洋蔥模型就已經實現了。

責任編輯:華軒 來源: web前端開發
相關推薦

2024-03-06 13:56:00

項目awaitpromise

2024-01-02 16:16:34

Promise前端

2024-07-02 09:03:48

2025-02-10 10:38:24

2012-10-29 11:01:17

2022-12-15 16:38:17

2023-10-24 09:25:23

IT技巧文化

2025-01-02 15:08:36

SpringBoot自動配置Java

2022-05-30 00:04:16

開源Github技巧

2010-08-25 11:14:05

云安全數據安全網絡安全

2024-03-21 09:58:27

ExtractTypeScript工具類型

2021-01-11 08:30:02

Dubbo服務

2024-04-01 07:51:49

Exclude?工具類型TypeScript

2023-01-03 11:47:47

2023-06-27 09:21:33

2025-05-09 09:26:12

2023-02-22 14:50:59

技術AI

2010-09-09 13:44:06

DIVCSS

2011-09-25 10:46:18

云計算安全

2010-08-11 16:43:05

職場
點贊
收藏

51CTO技術棧公眾號

人妻妺妺窝人体色www聚色窝| 久久久久亚洲av片无码下载蜜桃| 婷婷成人av| 一区二区高清在线| 免费试看一区| 999av视频| 国产婷婷精品| 欧美成年人网站| 九色porny自拍视频| 成人在线视频www| 黑人精品xxx一区| 国产又粗又硬又长| 激情视频在线观看免费| 国产专区综合网| 日韩av三级在线观看| 懂色av粉嫩av蜜臀av一区二区三区| 中文字幕日韩在线| 欧美日韩免费不卡视频一区二区三区 | 国产精品系列在线观看| 国产99久久精品一区二区| 免费在线观看av网址| 日韩三级在线| 亚洲国产三级网| 日本人妖一区二区| 亚洲国产精品va在线看黑人动漫| 北条麻妃在线视频| 国内精彩免费自拍视频在线观看网址| 国产精品第13页| 欧美三日本三级少妇三99| 超碰在线观看av| 国产一区二区调教| 国产欧美在线视频| 69亚洲精品久久久蜜桃小说| 国产精品地址| 超碰日本道色综合久久综合 | 欧美特黄不卡| 欧美日韩午夜在线视频| 久久九九国产视频| 毛片电影在线| 香港成人在线视频| 成人午夜视频在线观看免费| 影音先锋在线播放| 亚洲男人的天堂网| 好色先生视频污| 欧美日韩在线资源| 国产精品久久久久影视| 少妇精品久久久久久久久久| 男人的天堂在线视频| 99re成人精品视频| 好吊色欧美一区二区三区 | 中文字幕亚洲欧美日韩高清| 黑人巨大精品欧美| 亚洲三级网址| 亚洲片国产一区一级在线观看| 欧美深性狂猛ⅹxxx深喉| 成人自拍在线| 亚洲黄色片网站| 熟女人妻在线视频| 国产精品一区二区av日韩在线| 日韩黄色高清视频| 美女脱光内衣内裤| 波多野结衣在线观看一区二区| 一区二区三区黄色| 国产白丝一区二区三区| 国产精品久久久久久影院8一贰佰| 色综合伊人色综合网| 黄色录像二级片| 欧美精品97| 国内精品视频在线| 欧美bbbbbbbbbbbb精品| 亚洲欧美视频| 国产精品劲爆视频| 国产后入清纯学生妹| 成人午夜视频网站| 欧美精品一区在线| 午夜毛片在线| 亚洲一区在线电影| 久久精品.com| 96sao精品免费视频观看| 日韩欧美国产精品| 日本xxxxxxxxx18| 欧美疯狂party性派对| 欧美日本黄视频| 日韩不卡视频在线| 九九久久精品视频| 成人在线观看av| 久草在线免费福利资源| 中文字幕一区二区在线观看| 日韩免费在线观看av| 亚洲天堂av在线| 制服丝袜av成人在线看| 屁屁影院国产第一页| 成人毛片免费看| 欧美激情中文字幕在线| 高潮毛片又色又爽免费| 国产黄色91视频| 欧美二区三区在线| 国产福利在线播放麻豆| 日韩欧美在线字幕| 免费欧美一级片| 欧美色女视频| 欧美黄色片免费观看| 亚洲高清视频免费观看| 国产91在线观看丝袜| 老司机精品福利在线观看| 男女啪啪在线观看| 日韩欧美精品中文字幕| 在线免费看污网站| 亚洲婷婷伊人| 欧美激情视频一区二区| 中文无码av一区二区三区| 成人精品高清在线| 黄色www在线观看| 欧美三区四区| 亚洲精品91美女久久久久久久| 成人午夜免费影院| 久久亚洲欧美| 精品在线视频一区二区三区| 中文字幕免费高清电视剧网站在线观看| 色婷婷精品久久二区二区蜜臂av| 国产精品欧美性爱| 羞羞答答成人影院www| 青青青国产精品一区二区| 精品黑人一区二区三区在线观看| 中文乱码免费一区二区| 青青艹视频在线| xxxx日韩| 欧美极品美女视频网站在线观看免费 | 亚洲最大的成人网| yourporn在线观看中文站| 粉嫩老牛aⅴ一区二区三区| 久久久久99人妻一区二区三区| 欧美oldwomenvideos| 国产精品精品视频| 国产女人在线观看| 色综合久久久久综合| 日韩av一二区| 一本色道88久久加勒比精品| 国产精品久久亚洲7777| 美洲精品一卡2卡三卡4卡四卡| 正在播放一区二区| 天海翼在线视频| 狠狠久久亚洲欧美| 国产人妻互换一区二区| 高清精品久久| 久久中文精品视频| 国产伦精品一区二区三区免.费| 欧美激情在线免费观看| 五月婷婷激情久久| 久久人人88| 91在线视频免费| 在线中文字幕视频观看| 日韩亚洲国产中文字幕欧美| 青娱乐av在线| 成人高清免费观看| 国产男女无遮挡| 国产一区二区三区日韩精品| 国产精品第100页| 色网站在线看| 91麻豆精品91久久久久同性| 久久久久久久久久网站| 成人自拍视频在线观看| 免费无码毛片一区二三区| 一本色道久久综合亚洲精品酒店 | 俺去啦;欧美日韩| 国产一区二区自拍视频| 亚洲精品国产第一综合99久久| 波多野结衣中文字幕在线播放| 亚洲国产导航| 日本在线观看不卡| 白嫩亚洲一区二区三区| 欧美精品videosex牲欧美| 同心难改在线观看| 欧美日韩一区二区三区免费看| 男的操女的网站| 成人动漫av在线| 欧美牲交a欧美牲交aⅴ免费真| 九热这里只有精品| 99亚洲视频| 日韩精品伦理第一区| 亚洲精品aa| 97香蕉久久夜色精品国产| 国产在线视频网址| 欧美一区二区视频观看视频| 五月天婷婷丁香| 国产欧美视频在线观看| 能看毛片的网站| 免费视频一区| 国产91在线亚洲| 一区二区三区韩国免费中文网站| 91精品啪在线观看麻豆免费| 瑟瑟视频在线看| 日韩在线观看高清| 天堂中文在线资| 欧美精品日韩一本| 99精品视频99| 亚洲色图欧美偷拍| 国产交换配乱淫视频免费| 国产一区二区三区精品视频| 欧美亚洲一二三区| 综合天堂久久久久久久| 日韩欧美亚洲日产国| 永久免费精品视频| 国产精品亚洲激情| 九色porny自拍视频在线观看| www.国产一区| 欧美一区二区三区少妇| 日韩一级片在线播放| 欧美亚洲另类小说| 午夜电影网一区| 欧美日韩在线观看成人| 欧美韩国日本不卡| 无码精品一区二区三区在线播放| 精品一二三四在线| 国产一级不卡毛片| 国产免费成人| 国产一区 在线播放| 97精品视频在线看| 日本视频一区二区不卡| 久久中文字幕导航| 91精品黄色| av在线播放一区二区| 国产精品久久久久久久久久久久久久| gogo高清午夜人体在线| 欧美激情va永久在线播放| 老司机午夜在线视频| 色视频www在线播放国产成人| 天堂中文字幕av| 精品国产乱码久久久久久浪潮| 国产精品乱码久久久| 欧美日韩一本到| 中文字幕乱码中文字幕| 欧洲一区在线电影| 无码人妻精品一区二区三区9厂| 偷窥少妇高潮呻吟av久久免费| 久久久久久久久久久久久久免费看| 国产精品传媒视频| 中日韩一级黄色片| 亚洲欧洲av在线| 亚洲二区在线播放| 亚洲欧美一区二区三区国产精品| 最新日韩免费视频| 国产精品对白交换视频 | 国产精品第一页第二页第三页| 久久中文字幕精品| 中文字幕电影一区| 国产在线观看免费视频软件| 国产精品视频一二三| 日韩欧美在线视频播放| 亚洲图片激情小说| 国产女人18水真多毛片18精品| 亚洲欧美偷拍卡通变态| 欧美卡一卡二卡三| 夜夜嗨av一区二区三区网页 | 国产精品免费一区二区三区在线观看| 日本一区二区乱| 风间由美久久久| 少妇高潮一区二区三区| 欧美高清视频一区| 日韩国产综合| 在线视频91| 狠狠爱www人成狠狠爱综合网| 国产精品www在线观看| 国产精品丝袜xxxxxxx| 国产乱子夫妻xx黑人xyx真爽| 免费久久99精品国产自在现线| 激情视频免费网站| 国产伦精品一区二区三区免费 | 国产精品久久久久久久蜜臀| 成人欧美一区二区三区黑人一| 亚洲欧美国产77777| 日韩字幕在线观看| 91黄视频在线| av网站在线观看免费| 日韩电影视频免费| 91在线观看| 久久免费视频在线观看| 性欧美1819sex性高清| 国产日韩欧美视频| 国产成人澳门| 欧美午夜精品理论片a级大开眼界| 日韩av大片| 妺妺窝人体色777777| 日韩精品色哟哟| 天天爽夜夜爽视频| 91美女片黄在线| 亚洲最大的黄色网址| 精品久久久一区二区| 艳妇乳肉豪妇荡乳av| 欧美精品一区二区三区视频| 韩国三级在线观看久| 久久6免费高清热精品| 国模套图日韩精品一区二区| 成人性教育视频在线观看| 欧美福利在线播放网址导航| 中文字幕99| 久久国产精品久久w女人spa| 精品国产乱码久久久久久1区二区| 91丨九色porny丨蝌蚪| 亚洲一区电影在线观看| 欧美色播在线播放| 性少妇videosexfreexxx片| 亚洲天堂一区二区三区| 9lporm自拍视频区在线| 成人国产精品一区二区| 精品中文一区| 免费看欧美黑人毛片| 久久99久久99精品免视看婷婷 | 中文字幕亚洲成人| 日韩久久中文字幕| 欧美成人欧美edvon| 麻豆视频免费在线观看| 国产91亚洲精品| 日韩精品免费一区二区夜夜嗨 | 免费在线观看视频一区| 国产老熟女伦老熟妇露脸| 一区二区三区免费| 国产精品无码久久久久成人app| 亚洲欧美国产另类| 日本一级理论片在线大全| 成人欧美在线观看| 日本欧美国产| 久久久久久久少妇| www欧美成人18+| 国产做受高潮漫动| 亚洲福利视频久久| 密臀av在线| 国产高清一区视频| 欧美+日本+国产+在线a∨观看| 性刺激的欧美三级视频| 国产女同互慰高潮91漫画| av黄色在线播放| 亚洲人午夜色婷婷| 欧美亚洲大片| 五月婷婷一区| 男女激情视频一区| 极品尤物一区二区| 欧美亚洲动漫精品| 99se视频在线观看| 国产精品中文字幕久久久| 伊人久久大香线蕉无限次| 久久久久久久久久久久久久国产| 97se亚洲国产综合自在线| 日韩黄色一级大片| 日韩精品有码在线观看| xx欧美xxx| 四虎一区二区| 九色综合国产一区二区三区| 国产性生活大片| 日韩欧美一级特黄在线播放| 日韩免费影院| 国产一区自拍视频| 久久亚洲精品伦理| eeuss中文字幕| 欧美一区二区三区四区在线观看 | 性xxxxbbbb| 秋霞午夜一区二区| 欧美一区二区三| 天天干天天色天天干| 亚洲激情自拍视频| 天天综合网在线观看| 国产精品99久久久久久久久久久久| 欧美日韩国产免费观看视频| 中文字幕在线综合| 一区二区三区不卡在线观看| 色窝窝无码一区二区三区| 奇米4444一区二区三区| 日韩欧美高清在线播放| theporn国产精品| 亚洲一卡二卡三卡四卡| 韩国三级在线观看久| 91在线中文字幕| 亚洲精品九九| 少妇无套高潮一二三区| 日韩视频一区二区三区在线播放| 91破解版在线观看| 亚洲.欧美.日本.国产综合在线 | 成年人网站免费看| 91精品福利在线| 午夜小视频福利在线观看| 美乳视频一区二区| 男人的天堂亚洲| 国产在线视频欧美| 成人午夜精品视频| 黄网站免费久久| 国产精品久久亚洲| 中国日本在线视频中文字幕| 亚洲品质自拍视频| 国产视频手机在线播放| 久久男人av| 欧美高清无遮挡| 国产一区二区三区四区视频| 国产视频一区在线播放| 国产a级一级片| 朝桐光一区二区| 精品国产麻豆免费人成网站| 亚洲综合网在线| 7777精品久久久大香线蕉| 成av人片在线观看www| 午夜精品一区二区三区在线观看|