微信小程序异步请求封装方案

844 阅读1分钟

1.使用callback

1.1 config.js 定义配置信息

请求的通用信息

const config = {
  appkey:'zCr1cdeqweq',
  apiBaseUrl:'http://localhost:5300'
}

export {
  config
}

1.2 在utils包中定义http.js

import { config } from '../config/config'

class Http {
    static request({url, data, callback, method='GET'}){
        wx.request({
            url:`${config.apiBaseUrl}${url}`,
            data,
            header:{
                appkey:config.appkey
            },
            success:res=>{
                callback(res.data) //使用回调函数将数据传出去
            }
        })
    }
}

1.3 在model包中定义theme.js (业务对象)


import { Http } from '../utils/http';

class Theme{
    //获取首页LocationA
    static getHomeLocationA(callback){
        Http.request({
            url:`/theme`,
            data:{
                name:'t-1',//请求的参数
            },
            callback:data=>{
                callback(data) //回调函数中嵌套回调函数
            }
        })
    }
}

1.4 在home.js 调用

import { Theme } from '../../model/theme'

onLoad: function (options) {
    Theme.getHomeLocationA(data=>{
      this.setData({
        topTheme:data[0]
      })
    })
  },
  
  

分析可知 使用callback函数会出现函数嵌套

2.使用Promise

2.1 使用Promise封装Http.js

import { config } from '../config/config'

class Http{
    static request({url, data, method='GRT'}){
        return new Promise((resolve,reject)=>{
            wx.request({
                url: `${config.apiBaseUrl}${url}`,
                data,
                method,
                header: {
                  appkey: config.appkey
                },
                success:res=>{
                  resolve(res.data);
                },
                fail:err=>{
                  reject(err)
                }
            })
        })
    }
}

2.2 改写theme.js

import { Http } from '../utils/http';

class Theme {
  static  getHomeLocationA(params) {
    return Http.request({
       url: `/themes`,
       data: {
         names: params
       }
     })
   }
}

2.3 home.js

onLoad: function (options) {
    Theme.getHomeLocationA('t-1').then((data)=>{
      this.setData({
        topTheme:data[0]
      })
    })
}

3.终级解决方案 async await

  • 为了解决大量复杂不易读的Promise异步的问题,才出现的改良版

  • async必须声明的是一个function

  • async声明的函数的返回本质上是一个Promise。

  • await是在等待一个Promise的异步返回

3.1 将小程序内置非promise API转化为Promise请求

const promisic = function(func) {
    
    return function(params= {}) { 
        
        return new Promise((resolve,reject)=> {
            
            const args = Object.assign(params,{
                success:res=>{
                    resolve(res)
                },
                fail:err=>{
                    reject(err)
                }
            })
            func(args);
        })
    }
    
}

export {
    promisic
}

3.2 改写http.js

import { config } from '../config/config'
import { promisic } from './util'

class Http {
    static async request({url, data,  method = 'GET'}){
        return await promisic(wx.request)({
            url: `${config.apiBaseUrl}${url}`,
            data,
            method,
            header: {
                appkey: config.appkey
            },
        })
    }
}

export {
  Http
}

3.3 theme.js

import { Http } from '../utils/http';

class Theme {
  static async getHomeLocationA() {
   const res =  await Http.request({
      url: `/themes`,
      data: {
        names: 't-1'
      }
    })
    return res.data
  }
  
}

export {
  Theme
}

3.4 home.js

onLoad: async function (options) {
    const data =  await Theme.getHomeLocationA();
    this.setData({
      topTheme:data[0]
    })
},

使用了 async await 异步函数 变成了同步函数调用