详解在微信小程序的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 相关文章推荐
js 操作select相关方法函数
Dec 06 Javascript
一款Jquery 分页插件的改造方法(服务器端分页)
Jul 11 Javascript
js 判断所选时间(或者当前时间)是否在某一时间段的实现代码
Sep 05 Javascript
想学习javascript JS和jQuery哪个重要 先学哪个
Dec 11 Javascript
PHP自动加载autoload和命名空间的应用小结
Dec 01 Javascript
Vue三层嵌套路由的示例代码
May 05 Javascript
Vue.js实现的表格增加删除demo示例
May 22 Javascript
JS实现简单的抽奖转盘效果示例
Feb 16 Javascript
VSCode使用之Vue工程配置eslint
Apr 30 Javascript
node将geojson转shp返回给前端的实现方法
May 29 Javascript
jQuery表单校验插件validator使用方法详解
Feb 18 jQuery
uniapp 仿微信的右边下拉选择弹出框的实现代码
Jul 12 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
php 论坛采集程序 模拟登陆,抓取页面 实现代码
2009/07/09 PHP
一些PHP Coding Tips(php小技巧)[2011/04/02最后更新]
2011/05/02 PHP
PHP基于GD库的缩略图生成代码(支持jpg,gif,png格式)
2014/06/19 PHP
php与Mysql的一些简单的操作
2015/02/26 PHP
PHP文件上传、客户端和服务器端加限制、抓取错误信息、完整步骤解析
2017/01/12 PHP
php5.3/5.4/5.5/5.6/7常见新增特性汇总整理
2020/02/27 PHP
读jQuery之五(取DOM元素)
2011/06/20 Javascript
javascript结合ajax读取txt文件内容
2014/12/05 Javascript
JavaScript中通过提示框跳转页面的方法
2016/02/14 Javascript
模拟javascript中的sort排序(简单实例)
2016/08/17 Javascript
基于Vue渲染与插件的加载顺序的问题详解
2018/03/05 Javascript
深入理解Puppeteer的入门教程和实践
2019/03/05 Javascript
js常用正则表达式集锦
2019/05/17 Javascript
Bootstrap table 服务器端分页功能实现方法示例
2020/06/01 Javascript
Windows8下安装Python的BeautifulSoup
2015/01/22 Python
Python中的with语句与上下文管理器学习总结
2016/06/28 Python
python使用matplotlib绘制柱状图教程
2017/02/08 Python
在python3环境下的Django中使用MySQL数据库的实例
2017/08/29 Python
Python实现基于二叉树存储结构的堆排序算法示例
2017/12/08 Python
浅析python实现scrapy定时执行爬虫
2018/03/04 Python
Python简单生成随机数的方法示例
2018/03/31 Python
python 通过麦克风录音 生成wav文件的方法
2019/01/09 Python
用vue.js组件模拟v-model指令实例方法
2019/07/05 Python
cProfile Python性能分析工具使用详解
2019/07/22 Python
Python文字截图识别OCR工具实例解析
2020/03/05 Python
python 使用paramiko模块进行封装,远程操作linux主机的示例代码
2020/12/03 Python
欧洲最大的笔和书写专家:The Pen Shop
2017/03/19 全球购物
Pat McGrath Labs官网:世界上最有影响力的化妆师推出的彩妆品牌
2018/01/07 全球购物
数据库专业英语
2012/11/30 面试题
explicit和implicit的含义
2012/11/15 面试题
工业设计毕业生自荐信
2014/04/13 职场文书
学生个人评语大全
2015/01/04 职场文书
开票员岗位职责
2015/02/12 职场文书
2015年教师党员自我评价材料
2015/03/04 职场文书
项目战略合作意向书
2015/05/08 职场文书
Python语法学习之进程的创建与常用方法详解
2022/04/08 Python