收藏
回答

小程序wxRequest封装一个无痛刷新token方法?

当token过期后就去获取新的token,但要阻止同一个页面多个异步请求,在请求到新的token前,把请求任务放在队列,新token生成后再执行任务队列的请求,大概咋写啊,我怎么写都不对,就是怎么回调任务队列的请求

这是我现在的代码,大概思路是这样子,但是好像没有效果


var BASE_URL = 'https://www.****.com'

// 定义一个flag 判断是否刷新Token中
let isRefreshing = false;
// 保存需要重新发起请求的队列
let retryRequests = [];


class Request {
    /**
     * Request请求方法
     * @param  {String} url    链接
     * @param  {Objece} params 参数
     * @param  {Boolean} isToken  是否携带token
     * @return {Promise}       包含抓取任务的Promise
     */


    getApi(url, params, isToken, method) {
        if (isToken === undefined) isToken = true;
        if (method === undefined) method = 'GET';
        let token = wx.getStorageSync('logintoken') || '';
        let that = this;


        return new Promise((resolve, reject) => {
            //请求封装
            wx.request({
                url: `${BASE_URL}${url}`,
                method: method,
                data: params,
                header: {
                    'Content-Type': 'application/json',
                    "token": token,
                },
                success: res => {
                    if (res.statusCode == 200) {
                        const code = res.data.code || 200;
                        if (code == 200) {
                            resolve(res);
                        } else if (code == 10245) {
                           
                            // 返回10245表示token过期  多个异步请求 token 刷新处理
                            console.log('token过期了')
                            console.log('isRefreshing 状态',isRefreshing)
                            console.log('retryRequests 数组',retryRequests)


                            if(!isRefreshing){
                                // 改变flag状态,表示正在刷新Token中 不让其他请求进来
                                isRefreshing = true

                                                // 去获取新token 
                                 getApp().GetLogin().then(res=>{
                                        // 遍历执行需要重新发起请求的队列
                                    // retryRequests.forEach(cb => cb())
                                    // retryRequests =[]
                                })
                                .finally(() => {
                                    // 请求完成后重置flag
                                    isRefreshing = false;
                                })


                            }else{
                                // 正在刷新token,返回一个未执行resolve的promise
                                // 把promise 的resolve 保存到队列的回调里面,等待刷新Token后调用
                                // 原调用者会处于等待状态直到 队列重新发起请求,再把响应返回,以达到用户无感知的目的(无痛刷新)
                            
                                // 将resolve放进队列,用一个函数形式来保存,等token刷新后直接执行
                                
                                // retryRequests.push(()=>that(url, params, isToken, method));
                            }
                       
                        } else {
                            wx.showToast({
                                title: res.data.msg || '服务器出错',
                                icon: 'none',
                                duration: 1200,
                                mask: true
                            });
                            reject(res.data);
                        }
                    } else {
                        wx.showToast({
                            title: '[' + res.statusCode + '] 服务器出错,请重试',
                            icon: 'none',
                            duration: 1200
                        });
                        reject(res);
                    }


                },
                fail: err => {
                    console.log(err)
                    wx.showToast({
                        title: '网络错误',
                        icon: 'none',
                        duration: 1200
                    });
                    reject(err);
                },
                complete: () => {


                }
            });
        });
    }


}


let request = new Request();


module.exports = {
    request: request.getApi,
    url: BASE_URL
}


最后一次编辑于  2022-03-31
回答关注问题邀请回答
收藏

2 个回答

登录 后发表内容