微信小程序实践——用Promise 封装API


声明:本文转载自https://my.oschina.net/u/3396785/blog/1499246,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

为什么使用Promise

如果新接触 Promise 的话,在网上能找到很多介绍 Promise 及其使用的文章(比如:ECMAScript 6 入门 / Promise 对象),这里就不赘述了,简而言之就是用来处理异步调用的一大利器。

微信小程序的API都可以传入函数 success,fail 和 complete 来实现异步回调。

样例一

// 显示”载入中”,在一秒后消失 wx.showLoading({     title: "载入中",     success: function () {         setTimeout(function () {             wx.hideLoading()         }, 1000)     },     fail: function(){},     complete: function(){} }); 

原生的 success,fail 和 complete 已能够满足基本的异步回调了,但是如果遇到多个连续的阻塞任务,会造成多层嵌套(如样例二所示),就很奔溃。

样例二

// 显示“保存中”,一秒后隐藏,半秒后显示“载入中”,一秒后隐藏 wx.showLoading({     title: "保存中",     success: function () {         setTimeout(function () {             wx.hideLoading({                 success: function () {                     setTimeout(function () {                         wx.showLoading({                             title: "载入中",                             success: function () {                                 setTimeout(function () {                                     wx.hideLoading()                                 },1000)                             }                         })                     }, 500)                 }             })         }, 1000)     } }) 

上面的例子有七个阻塞任务:显示“保存中”,停顿一秒,隐藏,停顿半秒,显示“载入中”,停顿一秒,隐藏。从直觉上来思考,这些任务应该是以队列的形式存在,一个完成了再开始下一个,而非层层嵌套,这也是使用Promise的一大原因,可以链式调用。

上面的例子如果用Promise封装之后的API来写,看起来就非常直观(样例三)

样例三

wsAPI.taskSequence()     .then(() => wsAPI.showLoading({title: "保存中"}))     .then(() => wsAPI.sleep(1000))     .then(() => wsAPI.hideLoading())     .then(() => wsAPI.sleep(500))     .then(() => wsAPI.showLoading({title: "载入中"}))     .then(() => wsAPI.sleep(1000))     .then(() => wsAPI.hideLoading())     .then(() => console.log("done")) 

注: (A)=>{B} 是 ES6 的箭头函数,相当于 function(A){B},箭头函数不用显式 return。

比如 () => 5 就会 return 5

console.log((() => 5)()) // 5 

封装实现

wsAPI的源代码实现如下:

let nullFn = () => { }; function IllegalAPIException(name) {     this.message = "No Such API [" + name + "]";     this.name = 'IllegalAPIException'; } let services = {     sleep: (time) => {         return new Promise(function (resolve, reject) {             setTimeout(resolve, time);         })     },     stop: () => {         return new Promise(function (resolve, reject) {         })     },     taskSequence: () => {         return new Promise(function (resolve, reject) {             resolve()         })     } }; export let wsAPI = new Proxy(services, {     get: function (target, property) {         if (property in target) {             return target[property];         } else if (property in wx) {             return (obj) => {                 return new Promise(function (resolve, reject) {                     obj = obj || {};                     obj.success = (...args) => {                         resolve(...args)                     };                     obj.fail = (...args) => {                         reject(...args);                     };                     obj.complete = nullFn;                     wx[property](obj);                 });             }         } else {             throw new IllegalAPIException(property);         }      } }); 

wsAPI 用 Proxy(ECMAScript 6 入门 / Proxy)重新封装了 wx 的所有API。并新增了 sleep ,stop 和 taskSequence。sleep 用于阻塞一段时间;taskSequence 是一个空的 Promise,让代码看起来更整齐美观,可读性更好(样例四);stop 用于停止任务序列进行下去(样例五)

样例四

// taskSequence wsAPI.taskSequence()     .then(() => wsAPI.showLoading({title: "保存中"}))     .then(() => wsAPI.sleep(1000))     .then(() => wsAPI.hideLoading())     .then(() => wsAPI.sleep(500))     .then(() => wsAPI.showLoading({title: "载入中"}))     .then(() => wsAPI.sleep(1000))     .then(() => wsAPI.hideLoading())     .then(() => console.log("done"))  // 没有 taskSequence,第一个promise就和下面的不对齐 wsAPI.showLoading({title: "保存中"})     .then(() => wsAPI.sleep(1000))     .then(() => wsAPI.hideLoading())     .then(() => wsAPI.sleep(500))     .then(() => wsAPI.showLoading({title: "载入中"}))     .then(() => wsAPI.sleep(1000))     .then(() => wsAPI.hideLoading())     .then(() => console.log("done")) 

样例五

wsAPI.taskSequence()     .then(() => wsAPI.showModal({title: "保存", content: "确定保存?"}))     .then(res => {         if (!res.confirm) {             return wsAPI.stop();         }     })     .then(() => console.log("to save"))     .then(() => wsAPI.showLoading({title: "保存中"}))     .then(() => wsAPI.sleep(1000))     .then(() => wsAPI.hideLoading())     .then(() => console.log("done"))

本文发表于2017年08月02日 10:36
(c)注:本文转载自https://my.oschina.net/u/3396785/blog/1499246,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2142 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1