详解在微信小程序的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日历 推荐
Dec 03 Javascript
谷歌浏览器 insertCell与appendChild的区别
Feb 12 Javascript
JavaScript 语言的递归编程
May 18 Javascript
js 弹出新页面避免被浏览器、ad拦截的一种新方法
Apr 30 Javascript
jQuery实现鼠标经过弹出提示信息的地图热点效果
Aug 07 Javascript
js实现黑色简易的滑动门网页tab选项卡效果
Aug 31 Javascript
页面get请求 中文参数方法乱码问题的快速解决方法
May 31 Javascript
浅析jQuery Ajax通用js封装
Jun 22 Javascript
JavaScript中定时控制Throttle、Debounce和Immediate详解
Nov 17 Javascript
JavaScript在控件上添加倒计时功能的实现代码
Jul 04 Javascript
TypeScript中的方法重载详解
Apr 12 Javascript
在pycharm中开发vue的方法步骤
Mar 04 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
WAR3重制版DOTA 5V5初体验
2020/04/09 DOTA
php木马webshell扫描器代码
2012/01/25 PHP
php随机输出名人名言的代码
2012/10/07 PHP
PHP5常用函数列表(分享)
2013/06/07 PHP
PHP第三方登录―QQ登录实现方法
2017/02/06 PHP
Jsonp 跨域的原理以及Jquery的解决方案
2010/05/18 Javascript
js中用cssText设置css样式的简单方法
2016/09/19 Javascript
AngularJS中transclude用法详解
2016/11/03 Javascript
DropDownList控件绑定数据源的三种方法
2016/12/24 Javascript
微信小程序 swiper制作tab切换实现附源码
2017/01/21 Javascript
js实现textarea限制输入字数
2017/02/13 Javascript
基于Bootstrap框架实现图片切换
2017/03/10 Javascript
jQuery 导航自动跟随滚动的实现代码
2018/05/30 jQuery
Angular5集成eventbus的示例代码
2018/07/19 Javascript
js实现一个页面多个倒计时的3种方法
2019/02/25 Javascript
关于vue.js中实现方法内某些代码延时执行
2019/11/14 Javascript
微信小程序中data-key属性之数据传输(经验总结)
2020/08/22 Javascript
浅谈Python中的数据类型
2015/05/05 Python
Python虚拟环境Virtualenv使用教程
2015/05/18 Python
Python编写电话薄实现增删改查功能
2016/05/07 Python
python 获取页面表格数据存放到csv中的方法
2018/12/26 Python
关于Pytorch MaxUnpool2d中size操作方式
2020/01/03 Python
Python+Appium实现自动化测试的使用步骤
2020/03/24 Python
python 爬取小说并下载的示例
2020/12/07 Python
很酷的小工具和电子产品商城:GearBest
2016/11/19 全球购物
捷克多品牌在线时尚商店:ANSWEAR.cz
2020/10/03 全球购物
什么是托管函数?托管函数有什么用?
2014/06/15 面试题
Java程序员面试90题
2013/10/19 面试题
破坏寝室公物检讨书
2014/11/17 职场文书
2014年调度员工作总结
2014/11/19 职场文书
检讨书格式范文
2015/05/07 职场文书
运动会通讯稿50字
2015/07/20 职场文书
导游词之舟山普陀山
2019/11/06 职场文书
python tqdm用法及实例详解
2021/06/16 Python
Java数据开发辅助工具Docker与普通程序使用方法
2021/09/15 Java/Android
Java 通过手写分布式雪花SnowFlake生成ID方法详解
2022/04/07 Java/Android