function toAsync(names) {// 这里 names 期望是一个数组return (names || []).map(name => ({name,member: wx[name]})).filter(t => typeof t.member === "function").reduce((r, t) => {r[t.name] = promisify(wx[t.name]);return r;}, {});}
这个 toAsync 的用法大致是这样的
const awx = toAsync(["login", "request"]);await awx.login();await awx.request({...});
有些人可能更习惯单个参数传入的方式,像这样
const awx = toAsync("login", "request");
那么在 toAsync 的定义中,参数改为 ...names 就好,即
function toAsync(...names) { ... }
还没完,因为我不想在每一个 JS 文件中去 import { toAsync } from ...。所以把它在 App.onLaunch() 中把它注入到 wx 对象中去,就像这样
App({onLaunch: function() {// ...wx.async = toAsync;// ...}});
3. await 带来的神坑工具准备好了,代码也大刀阔斧地进行了改造,看起来舒服多了,一运行却报错!为什么???
先来看一段原来的代码,是这样的
wx.getStorage({key: "blabla",success: res => {// do with res}});
改造之后是这样
const res = await awx.getStorage({ key: "blabla" });// <== runtime error// do with res
awx.getStorage 抛了个异常,原因是叫 "blabal" 的这个数据不存在 。
为什么原来没有错,现在却报错?
因为原来没有定义 fail 回调,所以错误被忽略了 。但是 promisify() 把 fail 回调封装成了 reject() ,所以 awx.getStorage() 返回的 Promise 对象上,需要通过 catch() 来处理 。我们没有直接使用 Promise 对象,而是用的 await 语法,所以 reject() 会以抛出异常的形式体现出来 。
用人话说,代码得这样改:
try {const res = await awx.getStorage({ key: "blabla" });// <== runtime error// do with res} catch (err) {// 我知道有错,就是当它不存在!}
伤心了不是?如果没有伤心,你想想,每一个调用都要用 try ... catch ... 代码块,还能不伤心吗?
3.1. 忽略不需要处理的错误处理错误真的是个好习惯,但真的不是所有错误情况都需要处理 。其实要忽略错误也很简单,直接在每个 Promise 形式的异步调后面加句话就行,比如
const res = await awx.getStorage({ key: "blabla" }).catch(() => {});//^^^^^^^^^^^^^^^^ 捕捉错误,但什么也不干
稍微解释一下,在这里 awx.getStorage() 返回一个 Promise 对象,对该对象调用 .catch() 会封装 reject 的情况,同时它会返回一个新的 Promise 对象,这个对象才是 await 等待的 Promise 。
不过感觉 .catch(() => {}) 写起来怪怪的,那就封装成一个方法吧,这得改 Promise 类的原形
Promise.prototype.ignoreError = function() {return this.catch(() => { });};
这段代码放在定义 toAsync() 之前就好 。
用起来也像那么回事
const res = await awx.getStorage({ key: "blabla" }).ignoreError();
对于单个 await 异步调用,如果不想写 try ... catch ... 块,还可以自己定义一个 ifError(fn) 来处理错误的情况 。但是如果需要批量处理错误,还是 try ... catch ... 用起顺手:
4. 回到开始try {const storeValue = https://www.isolves.com/it/cxkf/ydd/xcx/2020-03-11/await awx.getStorage({});const settings = await awx.getSetting();const { code } = await awx.login();const userInfo = await awx.getUserInfo({ code });} catch (err) {// 处理错误吧}
看,不需要对每个异步调用定义 fail 回调,一个 try ... catch ... 处理所有可能产生的错误,这可不也是 async/await 的优势!
【在微信小程序中使用 async/await】
推荐阅读
- 温州黄汤冲泡步骤,温州平阳黄汤黄茶类中的黄小茶
- 北港毛尖适合小孩喝吗,什么是北港毛尖
- 程序员面试,如何在面试中介绍自己的项目经验?
- 黄茶的产地主要在哪里,在喧嚣的世界
- AI的下一站
- 芝加哥|人在职场,工作压抑很正常,不用怕,四条法则帮你忙
- 黄小茶适合孕妇喝吗,虎山黄茶孕妇可以使用吗
- 小户型买什么沙发好 小户型沙发的选购技巧
- 如何在电脑中裁剪图片 电脑上咋裁剪图片
- 香芋怎样冷冻保存