详解在微信小程序的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 相关文章推荐
Javascript 日期对象Date扩展方法
May 30 Javascript
基于Jquery的文字滚动跑马灯插件(一个页面多个滚动区)
Jul 26 Javascript
jquery 页面滚动到指定DIV实现代码
Sep 25 Javascript
使用JavaScript实现Java的List功能(实例讲解)
Nov 07 Javascript
基于jQuery实现网页进度显示插件
Mar 04 Javascript
JavaScript实现的圆形浮动标签云效果实例
Aug 06 Javascript
js实现简单排列组合的方法
Jan 27 Javascript
使用gulp搭建本地服务器并实现模拟ajax
Apr 05 Javascript
JS求1到任意数之间的所有质数的方法详解
May 20 Javascript
JS数组中对象去重操作示例
Jun 04 Javascript
vue+axios实现post文件下载
Sep 25 Javascript
Jquery使用each函数实现遍历及数组处理
Jul 14 jQuery
移动端(微信等使用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
雄兵连:天使彦天使彦为爱折翼,彦和炙心同时念动的誓言!
2020/03/02 国漫
将PHP作为Shell脚本语言使用
2006/10/09 PHP
一个捕获函数输出的函数
2007/02/14 PHP
如何离线执行php任务
2017/02/21 PHP
php 静态属性和静态方法区别详解
2017/04/09 PHP
jquery实现固定顶部导航效果(仿蘑菇街)
2013/03/21 Javascript
jquery遍历之parent()和parents()的区别及parentsUntil()方法详解
2013/12/02 Javascript
js中对象的声明方式以及数组的一些用法示例
2013/12/11 Javascript
Javascript中的默认参数详解
2014/10/22 Javascript
AngularJS入门教程之AngularJS指令
2016/04/18 Javascript
jQuery基本选择器(实例及表单域value的获取方法)
2016/05/20 Javascript
js动态获取子复选项并设计全选及提交的实现方法
2016/06/24 Javascript
javascript监听页面刷新和页面关闭事件方法详解
2017/01/09 Javascript
JavaScript实现的可变动态数字键盘控件方式实例代码
2017/07/15 Javascript
图解NodeJS实现登录注册功能
2019/09/16 NodeJs
JQuery使用属性addClass、removeClass和toggleClass实现增加和删除类操作示例
2019/11/18 jQuery
详解vue实现坐标拾取器功能示例
2020/11/18 Vue.js
vue使用lodop打印控件实现浏览器兼容打印的方法
2021/02/07 Vue.js
代码块高亮可复制显示js插件highlight.js+clipboard.js整合
2021/02/15 Javascript
python和shell变量互相传递的几种方法
2013/11/20 Python
python基础教程之Filter使用方法
2017/01/17 Python
Python 实现简单的shell sed替换功能(实例讲解)
2017/09/29 Python
Python使用pip安装报错:is not a supported wheel on this platform的解决方法
2018/01/23 Python
Python迭代器与生成器基本用法分析
2018/07/26 Python
详解Python打包分发工具setuptools
2019/08/05 Python
详解在Python中以绝对路径或者相对路径导入文件的方法
2019/08/30 Python
TensorFlow中如何确定张量的形状实例
2020/06/23 Python
通过实例简单了解Python sys.argv[]使用方法
2020/08/04 Python
纯CSS3实现3D旋转书本效果
2016/03/21 HTML / CSS
Smallable意大利家庭概念店:设计师童装及家居装饰
2018/01/08 全球购物
DELPHI面试题研发笔试试卷
2015/11/08 面试题
英语专业推荐信
2013/11/16 职场文书
《秋姑娘的信》教学反思
2014/02/28 职场文书
财政局党的群众路线教育实践活动整改方案
2014/09/21 职场文书
导游词书写之黄山
2019/08/06 职场文书
HTML静态页面获取url参数和UserAgent的实现
2022/08/05 HTML / CSS