zoukankan      html  css  js  c++  java
  • javascript 异步请求封装成同步请求

            此方法是异步请求封装成同步请求,加上token验证,环境试用微信小程序,可以修改文件中的ajax,进行封装自己的,比如用axios等

           成功码采用标准的 200 到 300 和304 ,需要可以自行修改

           同步任务接入之后,每个任务会进行token的验证,每个任务之间都是同步请求,包括token

    /**
     *  同步流请求
     *  token验证每个接口
     *  柯里化添加同步任务
     *  resolve返回res,cb
     *  reject 返回res,cb
     *  通过任务中断测试
     *  通过成功失败回调函数测试
     * 
     *  任务流 任务接入柯里化函数 currying(()=>{})              -->
     *  开始执行 currying() 进入g函数循环同步执行异步方法        -->
     *  执行异步方法 调用 rp 函数 封装 return new promise       -->
     *  rp 函数 执行判断 token 状态 进行处理
     */
    
    
    const regeneratorRuntime = require('./regenerator-runtime/runtime.js') //runtime类
    const errorMessage = '服务繁忙,稍后再试' //公共提示
    const successMessage = '完成' //公共提示
    
    class SuperClass {
      constructor() {
        Object.assign(this, {})
        //等待执行的接口
        this.wait = []
      }
    
      //Promise 请求接口
      rp(opts, skipToken = false) {
        const _t = this,
          data = opts.data || {}
        //小程序标识
        data.source = opts.sourceFlag ? data.source : 1;
    
        //请求信息
        console.group(`请求接口---${opts.url}`);
        console.log('接口信息', {
          opts,
          skipToken
        })
        console.groupEnd();
    
        return new Promise(function(resolve, reject) {
    
          opts.header = {
            "Content-Type": "application/json;charset=utf-8",
            //不需要走token的接口
            Authorization: !!opts.skipToken ? '' : (wx.getStorageSync('token') || '')
          }
    
          wx.request({
            url: '域名' + opts.url,
            data: data,
            header: opts.header,
            method: opts.method,
            dataType: 'json',
            responseType: 'text',
            success: function(res) {
              const {
                data
              } = res
    
              //成功 400为token失效 处理token失效问题 内层函数收集token失败码归并处理 
              if (data && (_t.successCode({
                  code: data.code
                }) || data.code == 400)) {
                resolve(data)
              } else {
                //其他不可预测为失败
                reject(data)
              }
            },
            fail: function(res) {
              reject(res.data)
            },
            complete: function(res) {
              //完成停止加载 
              wx.hideToast()
              opts.complete && opts.complete(res.data)
            }
          })
        })
      }
    
      //为空参数抛异常
      paramNoNull() {
        throw new Error('Missing parameter')
      }
    
      // g函数
      async g() {
        let _t = this,
          //中断任务
          isbreak = !1
    
        for (let [i, v] of _t.wait.entries()) {
          const r = await v().catch((res) => {
            //收集 所有的错误 统一执行 提示 或者错误回调
            const {
              cb,
              message
            } = res
    
            //同步流中断
            _t.clearWait()
            isbreak = !0;
            //没有回调函数执行错误提示
            'cb' in res ? cb() : (wx.factory._toast(message || errorMessage))
          })
    
          //任务执行成功
          if (!!r && r.constructor === Object && !!Object.keys(r).length) {
            const {
              res: {
                code,
                data,
                message
              },
              cb
            } = r
    
            //外层函数只处理成功状态
            if (_t.successCode({
                code
              })) {
              !!cb && cb()
    
              //同步流执行完成
              if ((i + 1) == _t.wait.length) {
                _t.clearWait()
                wx.factory._toast(message || successMessage)
              }
            } else {
              //同步流中断
              _t.clearWait()
              isbreak = !0
    
              wx.factory._toast(message || errorMessage)
            }
          }
    
          if (!!isbreak) {
            break
          }
        }
      }
    
      //清空任务
      clearWait() {
        this.wait = []
      }
    
      //柯里化
      currying() {
        const _t = this
        return (function(arg) {
          if (arg.length === 0) {
            _t.g()
          } else {
            [].push.apply(_t.wait, arg);
          }
        })(arguments)
      }
    
      //成功码
      successCode({
        code = 404
      }) {
        return (code >= 200 && code < 300) || code == 304
      }
    }
    
    //超类,实现多继承
    const decorator = Sup => class extends Sup {
      constructor(...args) {
        super(...args)
      }
    
      //获取token接口
      greatetoken(opts) {
        let codeOPts = JSON.parse(JSON.stringify(opts));
        codeOPts.url = `/getToken`
        codeOPts.method = `POST`
        codeOPts.data = {
          appIds: "xx",
          userId: 5
        }
        return super.rp(codeOPts, true).then((res) => {
          const {
            code,
            data
          } = res
          if (super.successCode({
              code: cb.code
            })) {
            if (!!data && !!data.token) {
              //全局token存储 方式为 storage
              wx.setStorageSync('token', data.token)
            } else {
              wx.factory._toast('获取token失败')
            }
          } else {
            wx.factory._toast('获取token失败')
          }
        }).catch(() => {
          wx.factory._toast('获取token失败')
        })
      }
    
      /**
       * 接口公共类 
       * 同步请求返回 Promise
       * 请求 token 为前提,为空 过期重新请求
       */
      async send(opts) {
        const token = wx.getStorageSync('token'),
          sendFun = (opts) => {
    
            //转化http请求 catch捕获promise的reject 展示接口级别错误 只做console打印 其他操作流入g函数(回调,提示)
            return super.rp(opts).catch(res => {
    
              //此处显示rp reject 报错
              console.group(`%c请求接口---${opts.url}---报错`, 'color:red;');
              console.log(` --> 参数`, {
                data: opts.data
              });
              console.log(` --> 返回值`, {
                res
              });
              console.groupEnd();
    
              //把错误信息传到 g 函数的catch里面
              opts.fail && opts.fail(res)
            })
          },
          successFun = async(opts) => {
            const cb = await sendFun(opts)
    
            //把成功信息传到g函数里面
            super.successCode({
              code: cb.code
            }) && opts.success && opts.success(cb)
          }
    
    
        if (!opts.skipToken) { //需要token请求
          if (!token) { //token为空 直接发起token请求
            await this.greatetoken(opts)
            await successFun(opts)
          } else {
            const cb = await sendFun(opts)
            if (!!cb) {
    
              //400 token过期  只有在存在token的情况下才会有时效的情况 归并处理
              if (cb.code == 400) {
                await this.greatetoken(opts)
                await successFun(opts)
              } else {
                //把成功信息传到g函数里面
                super.successCode({
                  code: cb.code
                }) && opts.success && opts.success(cb)
              }
            }
          }
        } else {
          await successFun(opts)
        }
      }
    
      post(opts) {
        opts.method = "POST";
        this.send(opts)
      }
    
      get(opts) {
        opts.method = "GET";
        this.send(opts);
      }
    }
    
    class Http extends decorator(SuperClass) { //子类
      constructor() { //继承参数
        super()
      }
    }
    
    export default new Http

        引入方式,全局调用

    import Http from './public/js/request'
    wx.http = Http

        调用执行,可用bind函数进行传参

        success返回为成功的,code值流入任务进行code值判断区分 resolve

        fail返回失败 reject

        complete执行的为方法

    Page({
       onLoad(){
         wx.http.currying(this.a.bind(this, {
          a: 1
        }))
        //进行传参bind
        wx.http.currying(this.b)
        wx.http.currying()
      },
      a() {
        const _t = this
        wx.factory._toast('加载a信息中...', 6000)
        return new Promise((resolve, reject) => {
          wx.http.post({
            url: 'a',
            data: {
              "params": {
                id:33
              }
            },
            success(res) {
              resolve({
                res,
    cb()=>{} }) }, fail(res) { reject({ res,
    cb()=>{} }) } }) }) }, b() { const _t
    = this wx.factory._toast('加载b信息中...', 6000) return new Promise((resolve, reject) => { wx.http.post({ url: 'b', data: { id:33 }, success(res) { resolve({ res }) }, fail(res) { reject({ res }) } }) }) } })
  • 相关阅读:
    jmeter的开启
    RobotFramework Selenium2 关键字
    RobotFramework测试环境搭建记录
    Posture Energy——姿态的能量
    在Centos中安装HustOJ实验记录
    江苏省综合素质评价平台视频操作演示和各角色说明书下载
    设计模式实战研磨 ——第1篇 UML环境搭建
    精益创新之设计思维研磨——《设计改变一切》书评
    Centos7中给gitLab汉化
    Centos7下安装gitLab
  • 原文地址:https://www.cnblogs.com/lmyt/p/11323640.html
Copyright © 2011-2022 走看看