这一篇内容比较短,介绍新增的语法糖。其实也不算新了。。。
async / await
这两个写法是 ES6 新加的特性,这让我们的代码更加简单明了。但是这并不是什么新技术,只是一个语法糖而已,它的本质还是 Promise。
await
我个人理解,await
是这两个语法糖的重点。它具有以下特点:
- 它后面需要跟一个 Promise,如果是一个值,则会自动包裹成一个 Promise
- 它需要在异步函数内部使用,也就是函数必须使用
async
修饰。
await
相当于前面提到过的 then
,使用 await
等待其后 Promise 的结果,只有获取了结果,程序才会继续执行,否则会一直等待。
async function get() {
let name = await new Promise(resolve => {
setTimeout(() => resolve("jeremyjone"), 1000);
});
console.log(name);
}
get(); // 等待1秒后,打印:jeremyjone
async
先来看一下 async
的写法:
async function get() {
return "jeremyjone";
}
此时 get
方法摇身一变,成了一个异步函数,它本质上返回一个 Promise,我们在使用的时候仍然可以通过 then
来使用。这也就是为什么 await
需要在 async
修饰的函数中,它们相互又可以成为一个链式操作:
// 接上例
get().then(v => console.log(v)); // jeremyjone
// 或者使用 await
let r = await get();
console.log(r); // jeremyjone
此时的 get
方法就相当于:
function get() {
return new Promise(resolve => {
resolve("jeremyjone");
});
}
这就是两个异步语法糖的用法。
捕获异常
捕获 async 的异常
因为 async 方法返回的是一个 Promise,所以和普通 Promise 的异常捕获一样,在调用时通过 .catch()
即可捕获。
async function get() {
return "jeremyjone";
}
// 调用
get()
.then(v => console.log(v))
.catch(err => console.log(err));
这是不存在任何问题的。
捕获 await 的异常
最简单的方式,我们可以通过 try...catch
直接捕获 await
语句的异常:
async function get() {
try {
let name = await new Promise(resolve => {
setTimeout(() => resolve("jeremyjone"), 1000);
});
console.log(name);
} catch (error) {
console.log(error);
}
}
但是这样不够优雅,结合我之前写过的内容,可以使用大神封装好的库。但是我又不想安装,所以直接自己封装成函数。
它的思路是这样的:写一个方法,包装所有的 Promise,让所有 Promise 同时返回成功的数据和异常的错误,然后由使用者抉择如何使用它们。如果成功,那么异常为 null
;如果失败,那么数据则为 undefined
。
不得不说,大神的思路简单清晰,而且代码非常简单,易于理解。
PS:有时候我们与大神差的真的只是思路。[偷笑]
function to(promise, errExt) {
return promise
.then(data => [null, data])
.catch(err => {
if (errExt) {
Object.assign(err, errExt);
}
return [err, undefined];
});
}
多么的清晰。将这个函数包装到所有需要使用的 Promise,现在 await
返回的将是一个具有两个参数的数组,第一个值是异常,第二个值是数据,随便使用。
async function get() {
const [err, name] = await to(
new Promise(resolve => {
setTimeout(() => resolve("jeremyjone"), 1000);
})
);
console.log(name);
}
是不是优雅了很多~~~
文章评论