小程序开发|小程序制作|小程序开发网

搜索

【微信小程序开发教程】用Promise 封装API

2017-8-14 18:01| 发布者: admin| 查看: 96| 评论: 4

摘要: 为什么使用Promise如果新接触 Promise 的话,在网上能找到很多介绍 Promise 及其使用的文章(比如:ECMAScript 6 入门 / Promise 对象),这里就不赘述了,简而言之就是用来处理异步调用的一大利器。 微信小程序的AP
为什么使用Promise如果新接触 Promise 的话,在网上能找到很多介绍 Promise 及其使用的文章(比如:ECMAScript 6 入门 / Promise 对象),这里就不赘述了,简而言之就是用来处理异步调用的一大利器。
微信小程序API都可以传入函数 successfail complete 来实现异步回调。 样例一
// 显示载入中,在一秒后消失wx.showLoading({ title: "载入中", success: function () { setTimeout(function () { wx.hideLoading() }, 1000) }, fail: function(){}, complete: function(){}});
原生的 successfail 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 ProxyECMAScript 6 入门 / Proxy)重新封装了 wx 的所有API。并新增了 sleep stop taskSequencesleep 用于阻塞一段时间;taskSequence 是一个空的 Promise,让代码看起来更整齐美观,可读性更好(样例四);stop 用于停止任务序列进行下去(样例五)


样例四
// taskSequencewsAPI.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"))


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

鲜花

握手

雷人

路过

鸡蛋
发表评论

最新评论

引用 admin 2017-9-13 15:35
支持支持顶顶顶
引用 xiaoxiao 2017-9-13 14:29
好 学习学习
引用 牛摩的 2017-8-25 16:36
多学咯学习咯
引用 xiaoxiao 2017-8-25 12:50
看不懂啊

查看全部评论(4)