微信小程序使用Promise对wx.request()进行封装详细教程(附完整代码)

Posted coderYYY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序使用Promise对wx.request()进行封装详细教程(附完整代码)相关的知识,希望对你有一定的参考价值。

1. 原生wx.request()的缺点

wx.request官网说明

  • 回调地狱,可能会出现多层success套用的情况(用Promise封装解决)
  • 效率低,代码冗杂,每次都要写共同的参数(比如headers,公共的url)
  • 可维护性差,后续查看和改代码不方便,封装后都在同一个文件,一目了然
wx.request(
  url: 'example.php', //仅为示例,并非真实的接口地址
  data: 
    x: '',
    y: ''
  ,
  header: 
    'content-type': 'application/json' // 默认值
  ,
  success (res) 
    console.log(res.data)
  
)

作为一个合格的前端开发,为了代码质量和可维护性(不是因为懒),肯定要对这种代码进行封装,来让我们的代码变得更优雅~~

2. 封装思路

所有的封装思路(无论是组件还是逻辑代码),总结起来一句话就是抽取共性
观察我们的网络请求代码,可以发现,有很多是一样的,如公共请求路径、对响应错误的处理方法、headers参数(如token)
不同的如具体的接口地址、请求类型、请求参数,我们封装的时候把相同的抽取成一个文件,不同的地方再进行传参即可。

3. 具体实现代码

先建一个api文件夹(叫什么都可以,但是为了规范化),在下面新建文件request.js

// ----http----
// api URL
const apiUrl = "https://接口地址:端口";// 公共的请求地址
// 封装微信请求方法
const request = (params) => 
  let url = params.url;
  let data = params.data;
  let method = params.method;
  let header = 
    "Content-Type": "application/json"
  ;

  // 鉴权验证,获取登录之后后端返回的token,存在即在头部Authorization写token,具体的看后端需求
  if (wx.getStorageSync("token")) 
    // header.Authorization = wx.getStorageSync("token");
    header.token = wx.getStorageSync("token");
  
  return new Promise((resolve, reject) => 
    wx.request(
      url: apiUrl + url, // api url
      method: method, // get/post
      data: data, // 请求参数
      header: header, // 头部
      success(res) 
        // 请求成功
        // 判断状态码---errCode状态根据后端定义来判断
        if (res.statusCode < 399) 
          if (res.data.Code === 401) 
            wx.showModal(
              title: "提示",
              content: "请登录",
              showCancel: false,
              success(res) 
                wx.navigateTo(
                  url: "/pages/login/login",
                );
              ,
            );
            reject(res.data);
          
          resolve(res.data);
         else 
          // 其他异常
          switch (res.statusCode) 
            case 404:
              wx.showToast(
                title: '未知异常',
                duration: 2000,
              )
              break;
            default:
              wx.showToast(
                title: '请重试...',
                duration: 2000,
              )
              break;
          
          reject("未知错误,请稍后再试");
        
      ,
      fail(err) 
        if (err.errMsg.indexOf('request:fail') !== -1) 
          wx.showToast(
            title: '网络异常',
            icon: "error",
            duration: 2000
          )
         else 
          wx.showToast(
            title: '未知异常',
            duration: 2000
          )
        
        reject(err);
      ,
      complete() 
        wx.hideLoading()
      ,
    );
  );
;

module.exports = 
  apiUrl,
  request,

然后再按业务需求,对具体的接口地址进行封装,比如,我这里在api文件夹下再新建一个user.js文件,里面放登录,注册的一些方法,请求类型和请求参数根据接口文档写。

import 
  request
 from "./request"


// 用户相关

// 登录
export const login = (params) => 
  return request(
    url: '/user/login',
    data: params,
    method: 'POST',
  )

// 注册
export const register = (params) => 
  return request(
    url: '/user/reg',
    data: params,
    method: 'POST',
  )

正式在项目中使用:

import 
  login
 from '../../../api/user'
// 点击登录的方法
handleLogin()
    login(
      name: xxx,
      password: xxx,
    ).then((res) => 
      if (res.code == 200) 
   		// 登录成功之后的处理
       else 
		// 登录失败的处理
      
    ).catch((res) => )

微信小程序使用Promise 实现对wx.request()请求封装

写在前面

我们在使用wx.request()请求网络操作的时候,里面的参数参数说多也不多,说少也不少,一旦请求多了,这写起来就很繁琐,而且一旦某些参数有变动,这修改起来太费事了。

wx.request()是一个异步 API它的结果返回的是Promise,微信小程序基础库 2.10.2 版本起,异步 API 支持 callback &promise 两种调用方式。

现在使用使用Promise 实现对wx.request()请求封装,可以帮助我们减少一些不必要的重复无用功。

具体实现


在小程序项目的utils下,新建一个request.js:,在这个文件里实现对wx.request()的封装:

request.js:


const baseURL = 'http://demo.api.xxx.com';

/**
 *  使用Promise 对wx.request进行分装
 * @param {*} params 
 */

function request(params = { methods, url, data }) {
  return  new Promise(function (resolve,reject) {
    wx.request({
      url: baseURL + params.url,
      method: params.method,
      data: params.data ? JSON.stringify(params.data) : null,
      header: { 
        'Content-Type': 'application/json',
        'accessToken': ''
       },
      timeout: 5000,
      success(res) { 
        if (res.statusCode == 200) {
          if (res.data.code == 0) {
            resolve(res.data);
          } else {
            wx.showToast({
              title: '提示',
              content: res.data.msg,
              showCancel: false,
              success:function(res) {}
            })
            reject(res,data);
          }
        } else {
          wx.showToast({
            title: '提示',
            content: '网络请求超时!',
            showCancel: false,
            success: function(res) {}
          })
          reject();
        } 

      },
      fail (err) {
        reject(err)
      }
    })
  })
}

module.exports = {
  request: request
}

新建api文件夹,在新建的js文件中,导入request.js,并实现封装增删改查的方法,命名自定义:

index.js:

const { request }  = require('../utils/request');

// 获取全部数据
function getList() {
  return request({
    url: '/manager/list', 
    method: 'GET'
  })
}

// 模糊查询
function getItemIds(params) {
  return request({
    url: '/manager/items?keyword=' + params,
    method: 'GET',
    params: params
  })
}

// 新增
function insertItem(params) {
  return request({
    url: '/manager/list'
    method: 'POST',
    data: params
  })
}

// 更新
function updateItem(params) {
  return request({
    url: '/manager/list'
    method: 'PUT',
    data: params
  })
}

// 删除
function deleteItem(id) {
  return request({
    url: '/manager/list'
    method: 'DELETE',
    params: id
  })
}


module.exports = {
  getList,
  insertItem,
  deleteItem,
  updateItem,
  getItemIds
}

如何使用

下面使用实现获取全部数据 & 关键词查询:

// index.js
const app = getApp();
const mRequest = require('../../api/index')

Page({
	data: {
		showItem: true, // 是否显示列表数据
		searchList: [], // 查询列表
		itemList: [], // 全部数据列表
		keyword: '', // 查询关键词
		roomId: undefined
	},

	// 加载列表数据
	onLoad() {
		const that = this
		mRequest.getList().then(res => {
			if (res) {
				// console.log(res);
				let listData = res.data;
				if (listData == null) {
					wx.showToast({
						title: '获取数据失败' + res.data.msg,
						icon: 'error',
						duration: 2000
					});
				} else {
					that.setData({
						showItem: true,
						itemList: res.data.items
					})
				}
			}
		}).catch(err => {
			console.log('error: ', err);
			that.setData({
				showItem: false
			})
		})
	},

	// 搜索/查询
	toSearch(e) {
		const that = this;
		console.log(that.data.keyword);
		mRequest.getItemIds(that.data.keyword).then(res => {
			if (res.data.items.length == 0) {
				wx.showToast({
					title: '暂无数据~',
					icon: 'loading',
					duration: 2000
				})
			} else {
				console.log(res);
				let searchList = res.data.items;
				that.setData({
					itemList: searchList
				})
				wx.showToast({
					title: '查询成功',
					duration: 2000
				})
			}
		}).catch(err => {
			console.log('error:', err);
			that.setData({
				showItem: false
			})
		})
	},

})

返回的数据

以上是关于微信小程序使用Promise对wx.request()进行封装详细教程(附完整代码)的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序中promise的使用

微信小程序封装Promise

微信小程序 在使用wx.request时显示加载中

微信小程序闭包

微信小程序wx.request的回调使用

微信小程序wx.request接口