日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[探索] 利用promise做一个请求锁

發布時間:2023/12/2 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [探索] 利用promise做一个请求锁 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在最近開發小程序的過程中,遇到一個需求,就是請求的時候header需要帶上accessToken, accessToken是通過登陸接口返回的參數,可能會出現過期的情況,則需要重新登陸,所以每次加載小程序都會進行一次本地儲存的accessToken校驗,但是再小程序的運行機制下,app的onLaunch,加載pages的onLoad會并發執行,在弱網的情況下,并發可能導致accessToken還沒校驗完,page的請求函數就開始執行了,這樣很容易會導致接口異常,本來的解決辦法是在每個page頁面調接口之前都await一下app.js里面checkAccessToken的方法,但是這樣寫起來不太友好

解決思路:

在request的基礎上封裝多一層鎖,當accessToekn校驗完成之前,其他進來的請求都進行等待,不進行請求,等待校驗完成,才開始其他請求

原理分析

  • 對原有的request請求做一次封裝
  • 利用promise的特性以及js對象存儲在內存的特性, 配合async/await,讓其他請求等待關鍵請求完成再開始請求,從而實現請求鎖
  • 首先等待關鍵請求完成了,再通過返回進入判斷是否經過需要
  • 代碼分析

    首先模擬一次請求

    // 模擬一次請求發起 const mockRequest = (name, time = Math.random() * 1000) =>new Promise(reslove => {console.log(`${name}---------------run`);setTimeout(() => {reslove(`${name}---------------done`);}, time);});

    定義請求鎖

    請求鎖要管理兩種狀態,一種是關鍵請求進行是狀態,一種是當關鍵請求失敗了之后,需要等待輔助操作完成的狀態

    const lock = { wait: null, runing: null };

    在request的基礎上加一層封裝

  • 參數設置兩種,withOutLock用于某些不需要等待的請求直接跳過邏輯,lockOthers用于鎖住在關鍵請求之后進來的請求
  • 關鍵請求進來直接執行,lock.runing直接賦予關鍵請求的pending狀態,當其他請求進來的時候,都直接等待,不進行請求發起,等主要請求進來完成之后,其他才開始執行
  • // 封裝模擬request const request = async (name,opts = { withOutLock: false, lockOthers: false, hasErr: false } ) => {// 不需要等待的請求直接執行if (opts.withOutLock) {const res = await mockRequest(`${name} - withOutLock`);console.log(res);return;}// 關鍵請求未執行完成 其他請求進入等待狀態if (lock.runing) {console.log(`${name}---------------wating...`);await lock.runing;}// 鎖住之后進來的請求if (opts.lockOthers) {lock.runing = mockRequest(name, 4000);let res = await lock.runing;// 清空進行鎖lock.runing = null;// 模擬關鍵請求失敗的 需要再次等待其他操作的情況 例如重新登陸等if (opts.hasErr) {lock.wait = mockRequest("關鍵請求異常處理", 4000);} else {console.log(res);return;}}// 等待模擬關鍵請求失敗的處理if (lock.wait) {console.log(`等待關鍵請求異常處理中...`);await lock.wait;// 清空等待鎖lock.wait = null;console.log(`關鍵請求異常處理完成`);}const res = await mockRequest(name);console.log(res);return; };

    模擬運行效果

    // 并發請求模擬 const mockConcurrent = () => {for (let i = 0; i < 5; i ) {setTimeout(() => {request(`并發請求${i}`, { withOutLock: i === 0 });}, Math.random() * 100);} };request("關鍵請求 - 其他需要等待完成才能進行", {lockOthers: true,hasErr: false });mockConcurrent();

    運行時效果

    最后

    經過同事的指點,未來還打算探究一下請求池,做請求上下文之類的實現

    demo代碼: 具體例子代碼demo參考

    純技術探索,坑點未知,歡迎指出錯誤以及不足的地方

    總結

    以上是生活随笔為你收集整理的[探索] 利用promise做一个请求锁的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。