Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何使小程序请求优雅化 #14

Open
mtonhuang opened this issue Dec 9, 2020 · 0 comments
Open

如何使小程序请求优雅化 #14

mtonhuang opened this issue Dec 9, 2020 · 0 comments

Comments

@mtonhuang
Copy link
Owner

mtonhuang commented Dec 9, 2020

前言

小程序原生的wx.request请求代码量繁琐,且容易造成回调地狱,不利于维护。利用Promise封装小程序请求,再封装包裹请求函数reqWrapper全局调用,大大减少代码量,提高可维护性。(注意,以下是以ts编写,可以根据需要改为js)

请求优雅化 VS 原生请求:

 // 优化后的请求
 API.getTest(entryData).then((res: any) => {})
    .catch((err: string) => {
        console.error(err)
 })

 // 原生的请求
 wx.request({
    url: 'test.php', //仅为示例,并非真实的接口地址
    data: {
      x: '',
      y: ''
    },
    method: 'POST',
    success (res: any) {
      console.log(res.data)
    },
    fail (res: any) {
      console.log(res.data)
  })

那么我们需要如何做呢?

一、引入登录态管理的网络请求组件weRequest

公司里一位大佬开发的登录态管理的网络请求组件weRequest,解决繁琐的小程序会话管理,具体可以移步学习。引入后按照文档指引配置request.ts。

let weRequest = require('./weRequest.js');
weRequest.init({
    // [必填] 后端在接口中返回登录成功后的第三方登录态
    getSession: function (res: any) {},
    // [必填] 用code换取session的CGI配置
    codeToSession: {
        // [必填] CGI的URL
        url: ``,
        // [必填] CGI中返回的session值
        success: function (res: any) {}
    },
    // [必填] 触发重新登录的条件,res为CGI返回的数据
    loginTrigger: function (res: any) {
        // 此处例子:当返回数据中的字段errcode等于-1,会自动触发重新登录
    },
    // 登录重试次数,当连续请求登录接口返回失败次数超过这个次数,将不再重试登录
    reLoginLimit: 2,
    // 触发请求成功的条件
    successTrigger: function (res: any) {
        // 此处例子:当返回数据中的字段ret_code等于0时,代表请求成功,其他情况都认为业务逻辑失败
        return res.ret_code == 0;
    },
    // 成功之后返回数据;可不传
    successData: function (res: any) {
        // 此处例子:返回数据中的字段data为业务接受到的数据
        return res;
    },
    // 当CGI返回错误时,弹框提示的标题文字
    errorTitle: function () {
        return '操作失败'
    },
    // 当CGI返回错误时,弹框提示的内容文字
    errorContent: function (res: any) {
        return (res.msg ? res.ret_msg : '操作失败');
    },
    doNotUseQueryString: true
});
export default weRequest

二、封装包裹请求函数

  • 1.引入第一步的配置文件request.ts
import weRequest from '../lib/request'
  • 2.封装包裹函数
/**
 * 包裹函数
 * @param opts weRequest参数
 * @param data 接口参数
 * @param url cgi路径
 * @param reqOpts 请求方式,默认为POST,可选
 */
let reqWrapper = (data: object, url: string, reqLoad?: boolean, reqOpts?: string) => {
    let param = Object.assign({}, data)
    return weRequest.request(Object.assign({}, {
        url: url,
        data: param,
        method: reqOpts? reqOpts : 'POST',
        showLoading: reqLoad? reqLoad : false //当为true时,请求该cgi会有loading       
    }))
}
export default {
    // 把请求export出去,比如
    saveTest(opts: RequestBody.saveTest): Promise<ResponseBody.saveTest> {
        return reqWrapper(opts, url , true)
    },
}

三、自定义报错提示

当我们封装完请求函数后,由于我们在第一步request.ts中,设置了触发请求成功的条件successTrigger,以及默认报错弹窗errorTitle、errorContent。所以一旦我们接口报错了,就会默认触发报错弹窗,我们在catch中也捕获不到err错误,但 weRequest 提供了自定义报错处理的函数fail,我们可以这样封装我们的函数:

/**
 * 包裹函数
 * @param opts weRequest参数
 * @param data 接口参数
 * @param url cgi路径
 * @param reqOpts 请求方式,默认为POST,可选
 * @param faliReport 是否有xxx函数,可选
 */
let reqWrapper = (data: object, url: string, faliReport?: any, reqLoad?: boolean, reqOpts?: string) => {
    let param = Object.assign({}, data)
    return weRequest.request(Object.assign({}, {
        url: url,
        data: param,
        showLoading: reqLoad ? reqLoad : false, //请求过程中是否展示loading
        method: reqOpts ? reqOpts : 'POST',
        fail: faliReport ? function () { faliReport() } : ''
    }))
}

export default {
    // 把请求export出去,比如
    saveTest(opts: RequestBody.saveTest,  faliReport: unknown): Promise<ResponseBody.saveTest> {
        return reqWrapper(opts, url , faliReport)
    },
}

基于上面的封装,我们可以在调用函数的时候,传入我们想自定义报错的xxx函数,这样就可以自定义报错提示了

四、小程序页面中使用

  • 1.在对应的页面引入第二步的文件,比如api.ts
import API from "../../api";
  • 2.请求格式如下
Page({
    data: {},
    onLoad(query: any) {
        this.test()
    },
    test: function () {
        const self = this;
        let entryData: RequestBody = {};
        let testErrorFunction = self. testErrorFunction; //如果需要自定义报错,则传入函数xxx
        API.getTest(entryData, self.testErrorFunction).then((res: any) => {})
        .catch((err: string) => {
            console.error(err)
        })
    },
     //自定义报错xxx函数
    testErrorFunction: function () {
       console.long('error')
    }
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant