美文网首页
小程序-解决同时多个异步请求引起的重复刷新token

小程序-解决同时多个异步请求引起的重复刷新token

作者: yun_xi | 来源:发表于2020-11-16 15:50 被阅读0次
不可避免的,我们需要在同一个页面同时执行多个异步的网络请求,为了避免token短时间内多次重复刷新,我们采取订阅的方式解决这个问题。
大概思路:由第一个请求去执行token的刷新,如果接下来还有其他的网络请求,我们让其等待执行,待token刷新结束之后,通知其他请求继续执行。(ps:因为我这里没有调用实际的接口,所以对于函数中接口地址及参数都省略掉了,在实际使用过程中,需要在函数中加上需要的参数)

第一步:创建一个NotificationCenter.js文件用来封装订阅流程

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

  this.registerNotification = function(name) {
    if (typeof notification[name] == 'undefined') {
      //注册通知
      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
}

第二步:创建一个Networking.js用来封装所有的网络请求过程

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

//请求数据
function requestData(success, failure) {
  fetchToken((successObj)=>{
    //在这里再执行接下来的数据请求即可
    //doNetWorking
    success(successObj);
  },(failObj)=>{
    failure(failObj)
  });
}

//判断是否存在token
function fetchToken(success, failure) {
  //这里根据实际情况去判断是否有必要去请求或者刷新token。我这里用过期时间和缓存是否存在做一个样例
  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以及其他相关信息缓存
        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中直接调用Networking.js中的requestData方法去执行网络请求即可
   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);
   });

可以发现,无论同时执行几个请求队列,都只会执行一次token的刷新过程。

相关文章

网友评论

      本文标题:小程序-解决同时多个异步请求引起的重复刷新token

      本文链接:https://www.haomeiwen.com/subject/deczbktx.html