详解在微信小程序的JS脚本中使用Promise来优化函数处理

作者:函数茶馆时间:2026-10-22 21:26:06浏览:98

本文详解如何在微信小程序JS中使用Promise优化异步函数处理。通过对比传统回调地狱,展示如何引入es6-promise组件,封装getUserInfo及网络请求等常用方法至utils.js,并利用then链式调用实现简洁易读的代码结构,提升小程序开发效率。

引言:Promise优化异步处理的必要性

在传统JavaScript开发中,开发者通常依赖回调函数处理逻辑。然而,随着回调层级的增加和异步复杂性的提升,代码可读性急剧下降。为解决这一问题,引入Promise机制成为优化JS函数处理的有效手段。它不仅能显著改善异步回调的可读性,还能使调用代码更加简洁。本文将具体介绍如何在微信小程序的JS代码中,利用Promise对各类函数进行封装与优化。

小程序传统回调处理模式分析

1、小程序传统的回调处理

以小程序生成时的默认app.js为例,其中自动包含一个getUserInfo函数,该函数采用传统的回调模式进行实现。


//app.js
App({
 onLaunch: function () {
 //调用API从本地缓存中获取数据
 var logs = wx.getStorageSync('logs') || []
 logs.unshift(Date.now())
 wx.setStorageSync('logs', logs)
 },
 
 getUserInfo:function(cb){
 var that = this
 if(this.globalData.userInfo){
  typeof cb == "function" && cb(this.globalData.userInfo)
 }else{
  //调用登录接口
  wx.login({
  success: function () {
   wx.getUserInfo({
   success: function (res) {
    that.globalData.userInfo = res.userInfo
    typeof cb == "function" && cb(that.globalData.userInfo)
   }
   })
  }
  })
 }
 },
 globalData:{
 userInfo: null,
 openid: null
 }
})

这种实现方式通过传入一个名为cb的回调函数来执行后续逻辑。为确保安全性,调用前还需额外判断cb类型是否为函数(typeof cb == "function")。尽管这种处理方式相对直观易懂,但在复杂场景下仍存在局限。

然而,当代码中包含大量异步操作,且必须保证这些操作按特定顺序执行时,传统回调方式会导致代码结构混乱,可读性极差。例如出现以下极端嵌套情况:


asyncFunc1(function(){
 //...
 asyncFunc2(function(){
 //...
 asyncFunc3(function(){
  //...
  asyncFunc4(function(){
  //...
  asyncFunc5(function(){
   //...
  });
  });
 });
 });
});

若改用Promise机制,仅需对原有逻辑进行简单包装即可解决上述问题。


function asyncFunc1(){
 return new Promise(function (resolve, reject) {
 //...
 })
}

Promise在小程序中的引入与配置

2、Promise的使用介绍

Promise的使用相对简便,初学者可参考阮一峰编写的Promise入门教程。若要在JS函数中引入Promise,需先包含对应的JavaScript组件。

开发者可在GitHub上下载es6-promise组件JS文件,并将其引入小程序项目中。

为便于管理,可在项目中创建一个辅助类文件utils.js,并在其中引入Promise脚本,具体配置如下。


const Promise = require('./Promise')

随后,在APP.js中修改原有的getUserInfo函数,具体实现如下。


//app.js
const utils = require('./utils/util.js')

App({
 onLaunch: function() {
  //调用API从本地缓存中获取数据
  var logs = wx.getStorageSync('logs') || []
  logs.unshift(Date.now())
  wx.setStorageSync('logs', logs)
 },

 getUserInfo() {
  return new utils.Promise((resolve, reject) => {
   if (this.globalData.userInfo) {
    resolve(this.globalData.userInfo)
   }
   return utils.getUserInfo().then(res => {
    resolve(this.globalData.userInfo = res.userInfo)
   })
  })
 },

 //获取系统信息
 getSystemInfo() {
  return new utils.Promise((resolve, reject) => {
   var that = this
   if (that.globalData.systemInfo) {
    resolve(that.globalData.systemInfo)
   } else {
    wx.getSystemInfo({
     success: function(res) {
      resolve(that.globalData.systemInfo = res);
     }
    })
   }
  })
 },
 //全局对象
 globalData: {
  userInfo: null,
  systemInfo: null
 },
 utils
})

观察可见,若需引入Promise处理,只需在原函数基础上增加一层函数体封装即可。


return new utils.Promise((resolve, reject) => {
  
  // 原来的函数体代码 
});

在调用时,可通过then函数链式处理后续逻辑,示例代码如下。


getUserInfo().then(user => this.setData({userInfo:user})).catch(console.log);

基于Promise的代码封装与复用实践

引入Promise后,为进一步实现代码复用,可将常见功能函数封装至utils.js中,从而实现跨模块的代码重用。


//用户登录
function login(){
 return new Promise((resolve,reject) => wx.login({
 success:resolve,
 fail:reject
 }))
}

//获取用户信息
function getUserInfo(){
 return login().then(res => new Promise((resolve,reject) => 
 wx.getUserInfo({
  success:resolve,
  fail:reject
 })
 ))
}


function requstGet(url,data){
 return requst(url,'GET',data)
}

function requstPost(url,data){
 return requst(url,'POST',data)
}

//封装Request请求方法
function requst(url,method,data = {}){
 wx.showNavigationBarLoading()
 data.method = method
 return new Promise((resove,reject) => {
 wx.request({
  url: url,
  data: data,
  header: {},
  method: method.toUpperCase(), // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
  success: function(res){
  wx.hideNavigationBarLoading()
  resove(res.data)
  },
  fail: function(msg) {
  console.log('reqest error',msg)
  wx.hideNavigationBarLoading()
  reject('fail')
  }
 })
 })
}

完成封装后,发布相应接口供其他模块调用即可。


//发布的接口
module.exports = {
 Promise,makeArray,getUserInfo,
 get:requstGet,post:requstPost,requst,decodeHtml,

 formatTime,getDateDiff
}

在页面中调用这些封装好的公用方法,示例代码如下(演示从指定地址获取数据并绑定至界面)。


  //使用Comprise的封装函数展现
  var url ='http://localhost:27206/api/Framework/Information/FindByCode';
  var companyurl = "http://www.iqidi.com";
  var json = {code: 'company'};
  app.utils.get(url, json).then(function(res) { 
  var data = { url: companyurl, image: res.Picture, content: res.Content };
  that.setData({
   item : data
  });
  WxParse.wxParse('content', 'html', data.content, that, 25);
  }); 

若使用原生的传统函数方式,实现代码则如下所示。


  // 使用标准的wx.request函数实现展现
  var url ='http://localhost:27206/api/Framework/Information/FindByCode';
  var companyurl = "http://www.iqidi.com";
  var json = {code: 'company'};
  wx.request({
   url: url,
   data: json,
   success: function(res) {
   console.log(res);
   var data = { url: companyurl, image: res.data.Picture, content: res.data.Content };
   that.setData({
    item : data
   });
   WxParse.wxParse('content', 'html', data.content, that, 25);
   }
  }) 

对于涉及复杂流程的函数处理,采用Promise机制能使代码结构更加简洁且易于阅读。

以上即为本文的全部内容,希望对各位的学习有所帮助,也欢迎大家继续支持本站。

作者最新文章