请老师看看还有什么要完善的地方

来源:11-8 Promise的正确用法

runzx

2018-08-22

通过这次课的收获, 结合前面全栈课内容,对小程序 http及用户身份token认证模块,我这几天重新精简,合并和重构后,在实用角度,请老师给些意见, 代码如下:

/**
 * 翟享 20180821
 * 昆明,重构base
 * promise, cache,token 
 * cachetime默认为0,不缓存。单位:秒
 * 通过times33生成缓存key 
 */
import { restUrl, api, appkey, tips } from './config'
import { times33 } from './hash'

class HTTP {
  constructor(app = getApp()) {    // App()页getApp()无效,此时用this传入app,其它页面可以不用传参数
    this.noRefetch = false
    this.app = app
    this.app.globalData.token || (this.app.globalData.token = wx.getStorageSync('token'))
  }
  
  request({ url, data = {}, method = 'GET', cachetime = 0 }) {

    return new Promise((resolve, reject) => {
        // 缓存判断
      if (cachetime) {
        let key = this._getKey(url, method, data),
        cacheData = wx.getStorageSync(key),
        timeStamp = Date.parse(new Date())
        if (cacheData && cacheData.data) {
          if (cacheData.expire > timeStamp) {
            return resolve(cacheData.data)
          }
          wx.removeStorageSync(key)    
        }
      }
    
      this._request({ url, resolve, reject, data, method, cachetime })
    })
  }
    
  _getKey(url, method, data) {
    let bid = this.app.globalData.bid,
        str = JSON.stringify(data)
    bid || (bid = '0')
    str = times33(url + method + bid + str) + ''    // wx只认string
    return str
  }
  
  _request({ url, resolve, reject, data, method, cachetime }) {
    wx.showNavigationBarLoading()
    wx.request({
        url: restUrl + url,
        method,
        data,
        header: {
            'content-type': 'application/json',
            'appkey': appkey,
            'authorization': 'zhai_token ' + this.app.globalData.token,
            // 'bisid': this.app.globalData.bisInfo.id
        },
        success: res => {
            let code = res.statusCode.toString()
            if (code.startsWith('2')) {
                resolve(res)
                this.noRefetch = false
                // console.log('--res--',res)
                this._processSuccess({ url, method, data,resData: res.data, cachetime })
            }
            else {
                if (code === '401' && !this.noRefetch) this._refetch({ url, resolve, reject, data, method })
                else {
                    reject()
                    this._processError(res)
                }
            }
          },
        fail: err => {
            reject()
            this._processError(err)
        },
        complete: res => {
            wx.hideNavigationBarLoading()
            wx.hideLoading()
        }
    })
  }
    
  _refetch(params) {
    this.getToken().then(res => {
        this.noRefetch = true
        this._request(params)
    })
  }
  
  _processSuccess({ url, method, data, resData,cachetime }) {
    if (cachetime) {
        let key = this._getKey(url, method, data),
        cacheData = {
            data: resData,
            expire: Date.parse(new Date()) + cachetime * 1000,
        }
        wx.setStorageSync(key, cacheData)
    }
  }
  
  _processError(err) {
    let msg = (err.data ? err.data.msg : false) || err.errMsg || '发生了一个错误'
    let code = err.statusCode, errMsg = tips[code] ? tips[code] : msg
    wx.showToast({
        title: errMsg,
        icon: 'none',
        duration: 5000
    })
  }
  
  // 从server取token,
  getToken() {
    return new Promise((resolve, reject) => {
        // 上传userInfo, globalData上没有从缓存取
        this.app.globalData.userInfo || (this.app.globalData.userInfo = wx.getStorageSync('userInfo') || {})
        wx.login({
            success: res => {
                this.request({
                    url: api.login,
                    data: { code: res.code, userInfo: this.app.globalData.userInfo },
                    method: 'POST'
                }).then(result => {
                    this.app.globalData.token = result.data.token
                    wx.setStorageSync('token', result.data.token)
                    wx.setStorageSync('userData', result.data)
                    this.app.globalData.isLoggedIn || (this.app.globalData.isLoggedIn = true)
                    resolve(result.data)
                }).catch(err => {
                    reject()
                    if (err.errMes === 'request:fail') {
                        wx.showModal({
                            title: '警告',
                            content: '你的网络环境差'
                        })
                    }
                })
            }
        })
    })      
  }                                                                
}

export { HTTP }


写回答

6回答

runzx

提问者

2018-09-24

我这是根据老师的设计理念,自己改写,这是我第4次重构。

多回头看,再对照老师讲的,就会有收获。

0
0

前端小白2018

2018-09-23

这么厉害!!!

收藏下。

0
0

runzx

提问者

2018-08-22

token通过服务器生成,我是根据全栈课里的用小程序 code码从微信服务器认证后数据生成,我用redis缓存,设定生命周期2小时
//生成令牌
static generateToken() {
    let randChar = this.randomWord(false, 32);
    let timestamp = Date.now();          
    let tokenSalt = secure.token_salt;   //salt盐
    return this.md5(randChar + timestamp + tokenSalt);
}


0
0

7七月

2018-08-22

都想拉你来做开源了

0
0

7七月

2018-08-22

风格上没什么问题。key还好,jwt token有很长。其实 服务器 这种key是有问题的,最好能够实现refresh token 刷新令牌

0
0

runzx

提问者

2018-08-22

对缓存key用hash生成,会不会画蛇添足?

如果直接返回 可能很长的字符串key, 对缓存读取速度会有多大影响?

0
4
runzx
回复
7七月
是一个技术栈,我先试试做个静态介绍网站。
2018-08-23
共4条回复

纯正商业级微信小程序应用实战,全方位小程序特性讲解

真实数据的高质量小程序项目,学会直接工作

4782 学习 · 2125 问题

查看课程