微信小程序中使用Promise进行异步流程处理

简介: 【更新说明】由于微信开发者工具和微信真机环境的不断升级,小程序中要使用Promise的话,已经不需要像文中描述的再引入第三方库如bluebird或es6-promise了,可直接使用。

【更新说明】
由于微信开发者工具和微信真机环境的不断升级,小程序中要使用Promise的话,已经不需要像文中描述的再引入第三方库如bluebird或es6-promise了,可直接使用。

我们知道,JavaScript是单进程执行的,同步操作会对程序的执行进行阻塞处理。比如在浏览器页面程序中,如果一段同步的代码需要执行很长时间(比如一个很大的循环操作),则页面会产生卡死的现象。

所以,在JavaScript中,提供了一些异步特性,为程序提供了性能和体验上的益处,比如可以将代码放到setTimeout()中执行;或者在网页中,我们使用Ajax的方式向服务器端做异步数据请求。这些异步的代码不会阻塞当前的界面主进程,界面还是可以灵活的进行操作,等到异步代码执行完成,再做相应的处理。

一段典型的异步代码类似这样:

function asyncFunc(callback) {
  setTimeout(function () {
    //在这里写你的逻辑代码
    //...

    //逻辑代码结束,执行一个回调函数
    callback();
  }, 5000);
}

或者:

function getAccountInfo(callback, errorCallback) {
  wx.request({
    url: '/accounts/12345',
    success: function (res) {
      //...
      callback(data);
    },
    fail: function (res) {
      //...
      errorCallback(data);
    }
  });
}

然后我们这样调用:

asyncFunc(function () {
  console.log("asyncFunc() run complete");
});

getAccountInfo(function (data) {
  console.log("get account info successfully:", data);
}, function () {
  console.error("get account info failed");
});

这是一种使用了回调函数来控制代码执行流程的方式。这样看起来没问题,也挺容易理解。

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

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

这样的代码可读性和可维护性可想而知了。还有,回调函数真正的问题在于:

它剥夺了我们使用 return 和 throw 这些关键字的能力。

那有什么办法来改善这个问题呢?答案是肯定的,Promise这种概念的产生,很好地解决了这一切。关于什么是Promise,一搜一大把介绍,我这里就不复制粘贴了,我主要是讲一下我们怎么用它来解决我们的问题。

我们来看一下,上面的例子如果使用Promise,它会是什么样子?我们先将这些函数变成Promise的方式:

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

// asyncFunc2,3,4,5也实现成跟asyncFunc1一样的方式...

然后看一下他们是怎么样被调用的:

asyncFunc1()
  .then(asyncFunc2)
  .then(asyncFunc3)
  .then(asyncFunc4)
  .then(asyncFunc5);

这样,这些异步函数就会按照顺序一个一个依次执行了。

ES6中原生支持了Promise,不过在原生不支持Promise的环境中,我们有很多第三方库来支持,比如Q.js和Bluebird。它们一般都除了提供标准Promise的API外,还提供了一些标准之外但非常有用的API,使得异步流程的控制更加优雅。

从微信小程序的API文档中我们可以看到,框架提供的JavaScript API中很多函数其实都是异步的,如wx.setStorage(), wx.getStorage(), wx.getLocation()等等,它们也是提供的回调的处理方式,在参数中传入success, fail,complete回调函数,就可以对运行成功或失败进行分别处理。

如:

wx.getLocation({ 
  type: 'wgs84', 
  success: function(res) { 
    var latitude = res.latitude 
    var longitude = res.longitude 
    var speed = res.speed 
    var accuracy = res.accuracy 
  },
  fail: function() {
    console.error("get location failed")
  }
})

我们能不能让微信小程序的异步API支持Promise呢?答案是肯定的,我们当然可以一个一个的用Promise去包装这些API,但是这个还是比较麻烦的。不过,由于小程序的API的参数格式都比较统一,只接受一个object参数,回调都是在这个参数中设置,所以,这为我们的统一处理提供了便利,我们可以写一个非侵入性的工具方法,来完成这样的工作:

假设我们将这个工具方法写到一个名为的util.js的文件中:

var Promise = require('../libs/bluebird.min')  //我用了bluebird.js

/**
 * 将小程序的API封装成支持Promise的API
 * @params fn {Function} 小程序原始API,如wx.login
 */
function wxPromisify(fn) {  
  return function (obj = {}) { 
    return new Promise((resolve, reject) => {      
      obj.success = function (res) {        
        resolve(res)      
      }      

      obj.fail = function (res) {        
        reject(res)      
      }      

      fn(obj)    
    })  
  }
}

module.exports = {  
  wxPromisify: wxPromisify
}

之后,我们来看一下如何使用这个方法,将原来回调方式的API变成Promise的方式:

var util = require('../utils/util')

var getLocationPromisified = util.wxPromisify(wx.getLocation)

getLocationPromisified({
  type: 'wgs84'
}).then(function (res) {
  var latitude = res.latitude 
  var longitude = res.longitude 
  var speed = res.speed 
  var accuracy = res.accuracy 
}).catch(function () {
  console.error("get location failed")
})

是不是很容易理解?

关于使用Promise处理异步流程,就先讲到这里,有什么疑问,可以留言给我。不对之处,欢迎指正。

谢谢大家阅读本文。

目录
相关文章
|
4月前
|
数据采集 存储 C++
Python异步爬虫(aiohttp)加速微信公众号图片下载
Python异步爬虫(aiohttp)加速微信公众号图片下载
|
8月前
|
安全 算法 小程序
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
522 28
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
|
8月前
|
小程序
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
554 1
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
|
人工智能 弹性计算 搜索推荐
打造个性化的微信公众号AI小助手:从人设到工作流程
在数字化时代,一个有个性且功能强大的AI小助手能显著提升用户体验。本文档指导如何在微信公众号上设置AI小助手“小智”,涵盖其人设、功能规划及工作流程设计,旨在打造一个既智能又具吸引力的AI伙伴。
1004 0
|
9月前
|
小程序
【01】微信支付商户申请下户到配置完整流程-微信商户申请-资料准备以及提交-微信商户密钥申请-申请+配置完整流程-优雅草卓伊凡
【01】微信支付商户申请下户到配置完整流程-微信商户申请-资料准备以及提交-微信商户密钥申请-申请+配置完整流程-优雅草卓伊凡
262 2
【01】微信支付商户申请下户到配置完整流程-微信商户申请-资料准备以及提交-微信商户密钥申请-申请+配置完整流程-优雅草卓伊凡
|
8月前
|
小程序 JavaScript 前端开发
微信小程序开发全流程:从注册到上线的完整指南
这篇文章详细记录了微信小程序的完整开发到最终上线的每一个步骤。适合对小程序开发感兴趣的个人开发者或希望了解完整流程的学习者,涵盖了云开发、事件绑定、生命周期管理、组件使用等关键内容。
3465 11
|
9月前
|
小程序 数据安全/隐私保护 开发者
【02】微信支付商户申请下户到配置完整流程-微信开放平台申请APP应用-微信商户支付绑定appid-公众号和小程序分别申请appid-申请+配置完整流程-优雅草卓伊凡
【02】微信支付商户申请下户到配置完整流程-微信开放平台申请APP应用-微信商户支付绑定appid-公众号和小程序分别申请appid-申请+配置完整流程-优雅草卓伊凡
579 3
|
Java API 开发者
Java如何实现企业微信审批流程
大家好,我是V哥。本文分享如何在企业微信中实现审批流程,通过调用企业微信的开放API完成。主要内容包括获取Access Token、创建审批模板、发起审批流程和查询审批结果。提供了一个Java示例代码,帮助开发者快速上手。希望对你有帮助,关注V哥爱编程,编码路上同行。
659 4
|
小程序 前端开发 算法
|
机器学习/深度学习 人工智能 小程序
【一步步开发AI运动小程序】三、运动识别处理流程
随着人工智能技术的发展,阿里体育等公司推出的“乐动力”、“天天跳绳”等AI运动APP备受关注。本文将引导您从零开始开发一个AI运动小程序,使用“云智AI运动识别小程序插件”。文章介绍了视频帧、帧率FPS、抽帧和人体识别等基本概念,并详细说明了处理流程,包括抽帧、人体识别检测、骨骼图绘制和运动分析等步骤。下篇将介绍如何在小程序中实现抽帧。