小程序-解決同時(shí)多個(gè)異步請(qǐng)求引起的重復(fù)刷新token

不可避免的,我們需要在同一個(gè)頁面同時(shí)執(zhí)行多個(gè)異步的網(wǎng)絡(luò)請(qǐng)求,為了避免token短時(shí)間內(nèi)多次重復(fù)刷新,我們采取訂閱的方式解決這個(gè)問題。
大概思路:由第一個(gè)請(qǐng)求去執(zhí)行token的刷新,如果接下來還有其他的網(wǎng)絡(luò)請(qǐng)求,我們讓其等待執(zhí)行,待token刷新結(jié)束之后,通知其他請(qǐng)求繼續(xù)執(zhí)行。(ps:因?yàn)槲疫@里沒有調(diào)用實(shí)際的接口,所以對(duì)于函數(shù)中接口地址及參數(shù)都省略掉了,在實(shí)際使用過程中,需要在函數(shù)中加上需要的參數(shù))

第一步:創(chuàng)建一個(gè)NotificationCenter.js文件用來封裝訂閱流程

function NotificationCenter() {
  let notification = {};
  //是否正在獲取token
  let isRequesting = false;

  this.registerNotification = function(name) {
    if (typeof notification[name] == 'undefined') {
      //注冊(cè)通知
      notification[name] = [];
    } else {};
  }

  this.addNotification = function(name, func) {
    if (typeof notification[name] != 'undefined') {
      notification[name].push(func);
    } else {}
  }

  this.distributeNotification = function(name, object) {
    if (typeof notification[name] != 'undefined') {
      notification[name].forEach((item) => {
        item(object);
      });
      notification[name] = [];
    }
    
  }
}

module.exports = {
  NotificationCenter: NotificationCenter
}

第二步:創(chuàng)建一個(gè)Networking.js用來封裝所有的網(wǎng)絡(luò)請(qǐng)求過程

import {NotificationCenter} from './NotificationCenter';
let center = new NotificationCenter();
center.registerNotification('token');

//請(qǐng)求數(shù)據(jù)
function requestData(success, failure) {
  fetchToken((successObj)=>{
    //在這里再執(zhí)行接下來的數(shù)據(jù)請(qǐng)求即可
    //doNetWorking
    success(successObj);
  },(failObj)=>{
    failure(failObj)
  });
}

//判斷是否存在token
function fetchToken(success, failure) {
  //這里根據(jù)實(shí)際情況去判斷是否有必要去請(qǐng)求或者刷新token。我這里用過期時(shí)間和緩存是否存在做一個(gè)樣例
  let currentTime = Date.now();
  let expires_in = wx.getStorageSync('expires_in');
  let token = wx.getStorageSync('token');
  if (token && currentTime < expires_in) {
      success(token);
  } else {
    if (center.isRequesting) {
      center.addNotification('token', function(item){
        if (item.length > 0) {
          success(item)
        } else {
          failure('獲取token失敗');
        }
      });
    } else {
      center.isRequesting = true;
      refreshToken((successObj)=>{
        //在這里將獲取的token以及其他相關(guān)信息緩存
        success(successObj);
        storageToken(successObj);
        center.distributeNotification('token',successObj);
        center.isRequesting = false;
      },(failObj)=>{
        failure(failObj);
        center.distributeNotification('token',failObj);
        center.isRequesting = false;
      });
    }
  }
}

//緩存token到本地
function storageToken (obj) {
  //將token緩存到本地
}

//刷新token
function refreshToken(success, failure) {
  setTimeout(() => {
    success('token123456');
  }, 3000);
}

module.exports = {
  requestData
}
第三步:在page中直接調(diào)用Networking.js中的requestData方法去執(zhí)行網(wǎng)絡(luò)請(qǐng)求即可
   networking.requestData((successObj)=>{
     console.log(successObj);
   },(failObj)=>{
     console.log(failObj);
   });
   networking.requestData((successObj)=>{
     console.log(successObj);
   },(failObj)=>{
     console.log(failObj);
   });
   networking.requestData((successObj)=>{
     console.log(successObj);
   },(failObj)=>{
     console.log(failObj);
   });

可以發(fā)現(xiàn),無論同時(shí)執(zhí)行幾個(gè)請(qǐng)求隊(duì)列,都只會(huì)執(zhí)行一次token的刷新過程。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容