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


Posted in Javascript onMarch 06, 2019

在我们传统的Javascript开发函数编写中,我们习惯了回调函数的处理,不过随着回调函数的增多,以及异步处理的复杂性等原因,代码越来越难读,因此诞生了使用Promise来优化JS函数处理的需求,引入Promise确实能够很好的解决异步回调函数的可读性等问题,同时也使得我们调用的时候代码简洁一些,本文介绍如何在小程序的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的回调函数进行处理,使用的时候为了安全性,还需要进一步判断其类型是否为函数:typeof cb == "function",这种处理还是相对比较易懂。

但是,如果我们一段代码中,异步操作太多,又要保证这些异步操作是有顺序的执行,那我们的代码就看起来非常糟糕,就像这样的极端情况:

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

如果我们改用Promise来处理,那么进行一层简单的包装即可。

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

2、Promise的使用介绍

Promise的使用相对比较简单,我们入门可以参考下相关介绍:阮一峰 promise入门,如果我们在JS函数里面引入它的话,那么需要包含对应的javascript组件

我们可以在Github上下载对应的组件JS,引入小程序项目即可:es6-promise

我们为了方便,在项目中创建一个辅助类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后,我们为了进一步实现代码的重用,可以把一些常见的函数放到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来处理,会显得更加简洁易读。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
使用jquery局部刷新(jquery.load)从数据库取出数据
Jan 22 Javascript
jquery ajax,ashx,json的用法总结
Feb 12 Javascript
前端必备神器 Snap.svg 弹动效果
Nov 10 Javascript
js操作css属性实现div层展开关闭效果的方法
May 11 Javascript
AngularJs 指令详解及示例代码
Sep 01 Javascript
Javascript实现前端简单的路由实例
Sep 11 Javascript
纯js实现手风琴效果代码
Apr 17 Javascript
前端开发之CSS原理详解
Mar 11 Javascript
vue将单页面改造成多页面应用的方法
Nov 25 Javascript
JavaScript学习教程之cookie与webstorage
Jun 23 Javascript
vue+springboot+element+vue-resource实现文件上传教程
Oct 21 Javascript
微信小程序实现文件预览
Oct 22 Javascript
移动端(微信等使用vConsole调试console的方法
Mar 05 #Javascript
利用Vconsole和Fillder进行移动端抓包调试方法
Mar 05 #Javascript
深入理解Puppeteer的入门教程和实践
Mar 05 #Javascript
[jQuery] 事件和动画详解
Mar 05 #jQuery
Vue 事件处理操作实例详解
Mar 05 #Javascript
Vue插槽原理与用法详解
Mar 05 #Javascript
JavaScript基于遍历操作实现对象深拷贝功能示例
Mar 05 #Javascript
You might like
DC的38部超级英雄动画电影
2020/03/03 欧美动漫
聊天室php&mysql(六)
2006/10/09 PHP
简单的PHP留言本实例代码
2010/05/09 PHP
PHP实现抓取迅雷VIP账号的方法
2015/07/30 PHP
通过代码实例解析PHP session工作原理
2020/12/11 PHP
控制打印时页眉角的代码
2007/02/08 Javascript
jquery 触发a链接点击事件解决方案
2013/05/02 Javascript
浏览器页面区域大小的js获取方法
2013/09/21 Javascript
js 通用订单代码
2013/12/23 Javascript
javascript实现的一个随机点名功能
2014/08/26 Javascript
jQuery实现在下拉列表选择时获取json数据的方法
2015/04/16 Javascript
大型JavaScript应用程序架构设计模式
2016/06/29 Javascript
jQuery dataTables与jQuery UI 对话框dialog的使用教程
2016/09/02 Javascript
常用原生js自定义函数总结
2016/11/20 Javascript
es6的数字处理的方法(5个)
2017/03/16 Javascript
vue.js声明式渲染和条件与循环基础知识
2017/07/31 Javascript
web前端vue实现插值文本和输出原始html
2018/01/19 Javascript
解决easyui日期时间框ie的兼容的问题
2018/03/01 Javascript
vue select组件的使用与禁用实现代码
2018/04/10 Javascript
通过实例了解JS执行上下文运行原理
2020/06/17 Javascript
详解Python的Django框架中的通用视图
2015/05/04 Python
Python中Class类用法实例分析
2015/11/12 Python
windows下安装python的C扩展编译环境(解决Unable to find vcvarsall.bat)
2018/02/21 Python
Python Pexpect库的简单使用方法
2019/01/29 Python
Python 实现两个服务器之间文件的上传方法
2019/02/13 Python
python-numpy-指数分布实例详解
2019/12/07 Python
python使用html2text库实现从HTML转markdown的方法详解
2020/02/21 Python
HTML5+CSS3网页加载进度条的实现,下载进度条的代码实例
2016/12/30 HTML / CSS
详解移动端HTML5页面端去掉input输入框的白色背景和边框(兼容Android和ios)
2016/12/15 HTML / CSS
微信小程序“圣诞帽”的实现思路详解
2017/12/28 HTML / CSS
英国顶级足球鞋的领先零售商:Lovell Soccer
2019/08/27 全球购物
Yahoo-PHP面试题3
2012/01/14 面试题
网页美工求职信范文
2014/04/17 职场文书
预备党员期盼十八届四中全会召开思想汇报
2014/10/17 职场文书
七年级作文之雪景
2019/11/18 职场文书
利用 SQL Server 过滤索引提高查询语句的性能分析
2021/07/15 SQL Server