详解在微信小程序的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 相关文章推荐
sina的lightbox效果。
Jan 09 Javascript
js+css使DIV始终居于屏幕中间 左下 左上 右上 右下的代码集合
Mar 10 Javascript
如何用JavaScript定义一个类
Sep 12 Javascript
详解javascript数组去重问题
Nov 06 Javascript
JavaScript计时器用法分析【setTimeout和clearTimeout】
Jan 18 Javascript
基于javascript实现最简单选项卡切换
Feb 01 Javascript
jQuery实现的浮动层div浏览器居中显示效果
Feb 03 Javascript
JS实现直接运行html代码的方法
Mar 13 Javascript
深入理解vue-router之keep-alive
Aug 31 Javascript
vue.js移动数组位置,同时更新视图的方法
Mar 08 Javascript
微信小程序绘制半圆(弧形)进度条
Nov 18 Javascript
JS+CSS实现过渡特效
Jan 02 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文件读写操作之文件读取方法详解
2011/01/13 PHP
学习ExtJS accordion布局
2009/10/08 Javascript
jquery实用代码片段集合
2010/08/12 Javascript
Jquery知识点一 Jquery的ready和Dom的onload的区别
2011/01/15 Javascript
js替代copy(示例代码)
2013/11/27 Javascript
JavaScript 32位整型无符号操作示例
2013/12/08 Javascript
jQuery常用操作方法及常用函数总结
2014/06/19 Javascript
jQuery不使用插件及swf实现无刷新文件上传
2014/12/08 Javascript
60个很实用的jQuery代码开发技巧收集
2014/12/15 Javascript
jquery实现仿新浪微博评论滚动效果
2015/08/06 Javascript
js实现表单Radio切换效果的方法
2015/08/17 Javascript
详解Jquery实现ready和bind事件
2016/04/14 Javascript
DropDownList实现可输入可选择(两种版本可选)
2016/12/07 Javascript
微信小程序下拉刷新界面的实现
2017/09/28 Javascript
JavaScript中正则表达式使数字、中文或指定字符高亮显示
2017/10/31 Javascript
js中bool值的转换及“&&”、“||”、 “!!”详解
2017/12/21 Javascript
Vue组件创建和传值的方法
2018/08/17 Javascript
详解webpack打包nodejs项目(前端代码)
2018/09/19 NodeJs
vue将单页面改造成多页面应用的方法
2018/11/25 Javascript
Vue退出登录时清空缓存的实现
2019/11/12 Javascript
jquery选择器和属性对象的操作实例分析
2020/01/10 jQuery
详解node.js 事件循环
2020/07/22 Javascript
[51:17]VGJ.T vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python实现用于测试网站访问速率的方法
2015/05/26 Python
基于Python log 的正确打开方式
2018/04/28 Python
用python wxpy管理微信公众号并利用微信获取自己的开源数据
2019/07/30 Python
python爬虫之遍历单个域名
2019/11/20 Python
Html5画布_动力节点Java学院整理
2017/07/13 HTML / CSS
基于HTML5的WebSocket的实例代码
2018/08/15 HTML / CSS
马云北大演讲完整版:真心话,什么才是阿里的核心竞争力?
2014/04/04 职场文书
成绩单公证书
2014/04/10 职场文书
法人任命书范本
2014/06/04 职场文书
户籍证明格式
2014/09/15 职场文书
绿里奇迹观后感
2015/06/15 职场文书
2016年优秀班主任先进事迹材料
2016/02/26 职场文书
MySql子查询IN的执行和优化的实现
2021/08/02 MySQL