查看: 501|回复: 2

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

[复制链接]

37

主题

43

帖子

9610

积分

论坛元老

Rank: 8Rank: 8

积分
9610
发表于 2017-8-14 18:01:24 | 显示全部楼层 |阅读模式

登录后查看更多内容,推荐微信扫码快速登录

您需要 登录 才可以下载或查看,没有帐号?【建议使用下方微信快捷登录注册】

x
为什么使用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"))


回复

使用道具 举报

0

主题

25

帖子

23

积分

新手上路

Rank: 1

积分
23
发表于 2017-8-25 12:50:44 | 显示全部楼层
看不懂啊
回复

使用道具 举报

37

主题

43

帖子

9610

积分

论坛元老

Rank: 8Rank: 8

积分
9610
 楼主| 发表于 2017-8-25 16:36:08 | 显示全部楼层

多学咯学习咯
回复

使用道具 举报

0

主题

4

帖子

11

积分

禁止发言

积分
11
发表于 2017-9-13 14:29:32 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

0

主题

2

帖子

9

积分

禁止发言

积分
9
发表于 2017-9-13 15:35:33 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

0

主题

1

帖子

10

积分

禁止发言

积分
10
发表于 2017-9-29 17:13:24 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

0

主题

2

帖子

11

积分

禁止发言

积分
11
发表于 2017-9-29 18:16:29 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

0

主题

93

帖子

97

积分

注册会员

Rank: 2

积分
97
发表于 2018-3-31 11:44:45 | 显示全部楼层

好 学习学习
回复

使用道具 举报

0

主题

72

帖子

78

积分

注册会员

Rank: 2

积分
78
发表于 2018-4-5 19:00:24 | 显示全部楼层
支持支持顶顶顶
回复

使用道具 举报

本版积分规则

QQ|Archiver|手机版|小黑屋|小程序大全|小程序开发者论坛-汇集最优质源码、开发者教程、小程序资源

GMT+8, 2018-8-15 02:04 , Processed in 0.198636 second(s), 10 queries , File On.

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表