文档章节

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

第九程序
 第九程序
发布于 2017/08/02 09:32
字数 781
阅读 1231
收藏 20
点赞 1
评论 4

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

© 著作权归作者所有

共有 人打赏支持
第九程序
粉丝 82
博文 142
码字总数 172691
作品 0
厦门
程序员
加载中

评论(4)

第九程序
第九程序

引用来自“alphasu”的评论

JS->JQUERY>ANGULAR->VUE->REACT->PROMISE,问下楼主,JS学到精了么
初学者
随机9380fa
随机9380fa
JS->JQUERY>ANGULAR->VUE->REACT->PROMISE,问下楼主,JS学到精了么
第九程序
第九程序

引用来自“Geomen”的评论

请问个初级的问题哦!
我把你的源码放到 utils/wsAPI.js里
在index.js里引入 var wsAPI = require('../../utils/wsAPI.js')
然后,使用点击事件触发
jumpTo: function(event){
console.log(event);
console.log(event.target.dataset.page)
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"))

},
报wsAPI.taskSequence is not a function;at "pages/index/index" page jumpTo function
我要怎么封装,怎么调用呢?
你好,文章最后有几个封装案例代码,可以试试
Geomen
Geomen
请问个初级的问题哦!
我把你的源码放到 utils/wsAPI.js里
在index.js里引入 var wsAPI = require('../../utils/wsAPI.js')
然后,使用点击事件触发
jumpTo: function(event){
console.log(event);
console.log(event.target.dataset.page)
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"))

},
报wsAPI.taskSequence is not a function;at "pages/index/index" page jumpTo function
我要怎么封装,怎么调用呢?
微信小程序开发--『狗蛋TV』

狗蛋TV 狗蛋TV是基于微信小程序开发的一款App。gordanLee每天都会推荐一首歌、一篇文章、一段短视频,每天用十分钟的细碎时光,点燃内心的光明。目前分为音乐,短视频,影评三个模块。 线上开...

李帅醒 ⋅ 05/15 ⋅ 0

分享几个微信小程序开发框架和工具

###【小程序开发框架】 1、官方框架MINA 小程序提供的开发框架为MINA框架,它类似于淘宝Weex、Vue框架。MINA框架通过封装微信客户端提供的文件系统、网络通信、任务管理、数据安全等基础功能...

codeGoogle ⋅ 04/18 ⋅ 0

mpvue学习笔记-之微信小程序数据请求封装

简介 美团出品的mpvue已经开源出来很久了,一直说要进行一次实践,这不最近一次个人小程序开发就用上了它。 看了微信官方的数据请求模块--request,对比了下get和post请求的代码,发现如果在...

愿爱无忧dk_ ⋅ 05/31 ⋅ 0

微信小程序 UI 组件库 - iView Weapp

iView Weapp —— 一套高质量的微信小程序 UI 组件库 iView Weapp 是什么? 微信小程序提供了自定义组件的功能,这使得 iView Weapp 成为了可能。小程序已经提供了很多组件和 API,但它们过于...

aresn ⋅ 06/11 ⋅ 0

如何为你的服务器申请免费的SSL证书

一、前戏 在文章《利用微信小程序和Kubernetes打造简易私有云(一、开篇)》中,本人计划用微信小程序作为K8S私有云的前端。由于之前对微信小程序也不了解,就不得不走一遍流程来学习实践,才...

宅楠军 ⋅ 05/10 ⋅ 0

编程微刊第四期文章汇总(2018.4)

编程微刊创立也有一段时间了,在此感谢一直关注我的小伙伴们,你们的关注和支持,是我每天不断更新的动力,我每个月会总结一期微刊,方便大家的阅读。 1. 推荐文章 这个时代,抛弃你的时候,...

祈澈姑娘 ⋅ 05/04 ⋅ 0

WordPress 版微信小程序 - weimi-GZU

微觅贵大微信小程序 —— WordPress 版微信小程序 功能清单: 1.缩略图的方式显示文章列表(首页,分类文章),包括显示文章分类和发布时间,加载分页。 2.在首页用轮播方式显示置顶文章。 ...

似最初 ⋅ 05/24 ⋅ 0

Python 的开源 Web 系统 - OSRoom

OSRoom —— 开源 Web 系统 OSROOM基于Flask + Mongodb3.4+ Redis开发。目前只在Ubuntu 14.04, 16.04测试过,其余Linux发行版还未测试。 可用于搭建(开发)个人网站,企业官网,微信小程序后...

我叫送小孩 ⋅ 05/14 ⋅ 0

微信小程序: 如何将一台电脑上的代码放到另一台电脑上安装运行

1。 首先,将代码放到固定的文件夹下 2。 启动微信小程序开发工具 3。在工具中点击 在弹出的页面选择: 点击 + 后,选择之前存放微信小程序的代码的文件夹,然后选中 确定即可。 ——————...

qq_31653405 ⋅ 04/23 ⋅ 0

奖金高达120万的微信小程序职业开发大赛,你还不来?

随着微信小程序掀起了微信生态中的重要革新,小程序开发也成为了时下受欢迎的开发实践方向。 如何开发一款优秀的小程序,既考验开发者的系统开发能力,也锻炼开发者的运营思维与商业意识。 ...

bjweimengshu ⋅ 04/19 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

java连接 mongo伪集群部署遇到的坑

部署mongo伪集群 #创建mongo数据存放文件地址mkdir -p /usr/local/config1/datamkdir -p /usr/local/config2/data mkdir -p /usr/local/config3/data mkdir -p /usr/local/config1/l......

努力爬坑人 ⋅ 26分钟前 ⋅ 0

React Native & Weex 区别

JS引擎 Weex使用V8, React native使用JSCore JS开发框架 ( Js Framework ) Weex基于vue.js(2W+ star)。小巧轻量的前端开发框架,组件化,数据绑定,2.0引入virtual dom。 ReactNative使用...

东东笔记 ⋅ 35分钟前 ⋅ 1

UIkit 分页组件动态加载简单实现

1. 问题描述 使用过UIkit分页组件的都清楚,UIkit的分页不能动态刷新数据,也就是不能在点击下一页的时候,动态从后台加载数据,并且刷新页数以及该页数上的数据,下面是一个简单实现,没有做...

影狼 ⋅ 36分钟前 ⋅ 0

Mobx入门之三:Provider && inject

上一节中<App/>组件传递状态temperatures给children -- <TemperatureInput />,如果组建是一个tree, 那么属性的传递则会非常繁琐。redux使用Provider给子组件提供store, connect将子组件和s...

pengqinmm ⋅ 38分钟前 ⋅ 0

魔兽世界 7.0版本 S23/S24/S25全职业普通+精锐套

  死亡骑士   (联盟)   (部落)   (精锐)   恶魔猎手   (联盟)   (部落)   (精锐)   德鲁伊   (联盟)   (部落)   (精锐)   猎人   (联盟) ...

wangchen1999 ⋅ 45分钟前 ⋅ 0

maven顶级pom和子pom的版本号批量修改

当一个版本发布,新起一个版本时,我们只需要手动修改一下项目中pom.xml的版本号就可以了。但是如果这个maven项目有很多的子模块项目,那么一个个手动的去改就显得费时费力又繁琐了。还好,m...

ArlenXu ⋅ 54分钟前 ⋅ 0

天气预报接口选择

分为两类收费和免费的 收费的 收费的就不用说了,各种云市场上都有 免费的 免费的最权威的就2个 中国天气网 中国万年历提供的天气API 百度 万年历提供的API有json和xml格式,xml提供的信息更...

SimonAt ⋅ 55分钟前 ⋅ 0

Elasticsearch究竟要设置多少分片数?

0、引言 在构建Elasticsearch集群的初期如果集群分片设置不合理,可能在项目的中后期就会出现性能问题。Elasticsearch是一个非常通用的平台,支持各种各样的用例,并且为数据组织和复制策略提...

tqyin ⋅ 56分钟前 ⋅ 0

php 如何获取指定session_id中的数据

代码如下: $sess_name = session_name(); $sess_id = $_POST[$sessname]; session_id($sess_id);//根据当前session_id=5f0bv0dke3p5tqdcuujtl3kkv7,获取指定session,如果session_id 存在,則......

qimh ⋅ 59分钟前 ⋅ 0

C++使用try,catch在VS2015中捕获异常

下面的代码: #include "stdafx.h"#include <iostream>int main(){try{char* pch;pch = (char*)00001234; //给予一个非法地址 *pch = 6; //对非法地址赋值,会造...

极客行 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部