评论

request封装

request封装

fetch.js

const api = 'www.qq.com'
export const Fetch = ({
  url = '',
  data = {},
  header = { "content-type": "application/json" },
  method = 'GET',
  api = Api
}) => {
  return new Promise((resolve, reject) => {
    wx.request({
      url: api + url,
      header: header,
      method: method,
      data: data,
      success: res => {
        // 成功时的处理
        if (res.data.error == 0) {
          resolve(res.data);
        } else {
          reject(res.data);
        }
      },
      fail: err => {
        reject(err);
      }
    })
  })
}

api.js

import { Fetch } from './fetch.js';

export const PostMiniList = data => {
  return Fetch({
    url: '/post/post_mini_list.json',
    data: data,
    method: 'POST',
    header: {
      'content-type': 'application/x-www-form-urlencoded'
    }
  })
}

export const GetMiniList = data => {
  return Fetch({
    url: '/get/get_mini_list.json',
    data: data
  })
}

index.js

import { PostMiniList, GetMiniList } from './api.js';

PostMiniList({
  a:1,
  b:2
}).then(
  res => {
    // 成功处理
  },
  err => {
   // 失败处理
  }
)

GetMiniList({
  a:1,
  b:2
}).then(
  res => {
    // 成功处理
  },
  err => {
   // 失败处理
  }
)

把所有api放在api.js里统一管理,利用promise使我们只关注返回的结果

最后一次编辑于  2019-05-06  
点赞 7
收藏
评论

3 个评论

  • 张小康
    张小康
    2019-05-10

    将api转换为返回promise对象(引用自https://github.com/youngjuning/wxPromise

    //将转换为Promise对象的api挂载在该对象下
    wx.pro = {}
    //微信api请求失败标识
    const WX_FAIL = Symbol('微信API请求失败');
     
    /**
     * 将函数变成Promise对象,并添加finally,意为无论success还是fail都会执行的操作
     * fail默认返回码为wx_fail,方便catch捕获后明确错误原因
     */
    const promisify = (api) => {
      return (options, ...params) => {
        return new Promise((resolve, reject) => {
          api(Object.assign({}, options, {
            success: resolve,
            fail: (err) => {
              reject({
                code: WX_FAIL,
                msg: err
              })
            }
          }), ...params)
          Promise.prototype.finally = function (callback) {
            let P = this.constructor
            return this.then(
              value  => P.resolve(callback()).then(() => value),
              reason => P.resolve(callback()).then(() => { throw reason })
            )
          }
        })
      }
    }
    /**
     * 将Promise化的api挂在在wx.pro对象下,你仍然可以使用wx.api调用源生api
     * 注:对于同步操作,wx.pro.api 与 wx.api 相同
     * 同步操作包括:(即没有success、fail和complete属性的api)
     * 1、...Sync【√】
     * 2、on...【√】
     * 3、create... 除了 createBLEConnection【√】
     * 4、...Manager【√】
     * 5、pause...【√】
     * 6、stopRecord、stopVoice、stopBackgroundAudio、stopPullDownRefresh【√】
     * 7、hideKeyboard、hideToast、hideLoading、showNavigationBarLoading、hideNavigationBarLoading【√】
     * 8、canIUse、navigateBack、closeSocket、pageScrollTo、drawCanvas【√】
     */
    const wxPromise = () => {
      // 将 promise 方法 挂载到 wx.pro 对象上
      for (let key in wx) {
        if (wx.hasOwnProperty(key)) {
          if (/^on|^create|Sync$|Manager$|^pause/.test(key) && key !== 'createBLEConnection' || key === 'stopRecord' || key === 'stopVoice' || key === 'stopBackgroundAudio' || key === 'stopPullDownRefresh' || key === 'hideKeyboard' || key === 'hideToast' || key === 'hideLoading' || key === 'showNavigationBarLoading' || key === 'hideNavigationBarLoading' || key === 'canIUse' || key === 'navigateBack' || key === 'closeSocket' || key === 'closeSocket' || key === 'pageScrollTo' || key === 'drawCanvas') {
            wx.pro[key] = wx[key]
          } else {
            wx.pro[key] = promisify(wx[key])
          }
        }
      }
    }
    wxPromise();

    封装请求

    const post = function (url, params, {
      encode = true,
      duration,
      timeout = 30000,
      isShow = true
    } = {}) {
      if (isShow) {
        wx.showLoading({
          title: '请等待...',
          icon: 'loading',
          mask: true
        });
      }
      const clock = timerTask(timeout);
      return Promise.race([wx.pro.request({
        url: config.reqSite + 'api/' + url,
        data: assembleRequestData(params, encode),
        header: getReqHeader(),
        method: 'POST'
      }), clock.timer]).then(res => {
        clearTimeout(clock.id);
        //处理响应体
        return handleResponse(res);
      }).then(res => {
        if (isShow) {
          wx.hideLoading();
        }
        //判断业务状态是否为成功
        if (res.data.RetStatus == 'S') {
          //设置本地cookie
          setLocalCookie(res);
          return res.data.RetData;
        } else {
          //业务状态为失败时,默认弹出提示信息
          myToast(res.data.RetMsg, duration);
          return Promise.reject(res);
        }
      }).catch(err => {
        //微信请求失败时调用
        if (err.code == WX_FAIL) {
          if (isShow) {
            wx.hideLoading();
          }
          myToast(MSG_NONETWORK);
        }
        return Promise.reject(err);
      }).finally(() => {
        clearTimeout(clock.id);
      })
    }
      


    2019-05-10
    赞同
    回复
  • -
    -
    2019-05-07

    学了阮一峰的es6后一直想用Promise 封装下request,有现成的就不用这么麻烦了

    2019-05-07
    赞同
    回复
  • 金钱豹
    金钱豹
    2019-05-06
    request: function (object) {
          //检查token
          if (!object.isNoNeedLogin && !this.checkToken()) {
             wx.showToast({
                title: "请重新登录",
                icon: "none"
             })
             wx.clearStorageSync();
             setTimeout(function () {
                wx.redirectTo({
                   url: '/pages/user/login',
                })
             }, 500)
             return false;
          }
          wx.showNavigationBarLoading();
          wx.request({
             url: this.siteInfo.apiBaseUrl + object.url,
             header: object.header || {
                'token': this.getToken()
             },
             data: object.data || {},
             method: object.method || "GET",
             dataType: object.dataType || "json",
             success: function (res) {
                if (object.success) {
                   object.success(res);
                }
                if (res.data.code == 1001) {
                   wx.showToast({
                      title: res.data.msg,
                      icon: "none"
                   })
                   wx.clearStorageSync();
                   setTimeout(function () {
                      wx.redirectTo({
                         url: '/pages/user/login',
                      })
                   }, 500)
                   return false;
                } else if (res.data.code > 0) {
     
                } else {
                   wx.showToast({
                      title: res.data.msg ? res.data.msg : "系统繁忙,请稍后再试",
                      icon: "none",
                      duration: 2000
                   })
                }
             },
             fail: function (res) {
                //wx.hideLoading();
                console.warn('--- request fail >>>');
                console.warn(res);
                console.warn('<<< request fail ---');
                wx.showToast({
                   title: "网络请求出错,请检查网络设置,错误码:".res.statusCode,
                   icon: "none"
                })
                // wx.showModal({
                //    title: "网络请求出错",
                //    content: "网络请求出错,请检查网络设置",
                //    showCancel: false,
                //    success: function (res) {
                //       if (object.fail) {
                //          object.fail(res);
                //       }
                //    }
                // });
             },
             complete: function (res) {
                if (res.statusCode != 200) {
                   console.log('--- request http error >>>');
                   console.log(res.statusCode);
                   console.log(res.data);
                   console.log('<<< request http error ---');
                }
                if (object.complete) {
                   object.complete(res);
                }
                wx.hideNavigationBarLoading();
             }
          });
       }

    拿走不谢,不用那么麻烦

    2019-05-06
    赞同
    回复 4
    • 2019-05-07

      你写的很不错,但是并不适用于所有人,很多需求其实是在请求接口的页面去处理结果,你满足不了这种需求,除非用object里添加回调函数,但是那样更麻烦

      2019-05-07
      回复
    • 2019-05-07

      或者说,你的意思是每个页面都放一个request方法?那你的api怎么统一管理?代码有多冗余?

      2019-05-07
      回复
    • 金钱豹
      金钱豹
      2019-05-07回复

      封装到APP.JS里面,需要什么回调函数就自己添加了,我这边状态码不多,足够用了,原生的wx.request 一样的用法。常见的几种状态  异常,失败,成功,未登录几个常规的都有处理。增强了原生wx.request 的用法

      2019-05-07
      2
      回复
    • 2019-05-07回复金钱豹

      兄弟,还是你的接口太少,等你的项目涉及到几十几百个接口的时候,你就知道对接口进行统一管理有多重要了

      2019-05-07
      2
      回复
登录 后发表内容