作为一项ES6推出的异步编程解决方案,async/await构成了JavaScript的新风景线,在优化异步操作的同时,也显著地缩短了代码量。然而,不管在哪里,我们都不可能看到完美的异步解决方案,await-to-js诞生的意义也是如此——时常在一行代码中把全部的可能性拓展,碰到错误也能优雅地处理。这篇文章将会从await-to-js的优势和使用示例着手,深入探讨这款await-friendly库。
一、快速入门
在介绍await-to-js能做些什么之前,让我们先来看看在实际代码里,如何对一个promise做错误处理。我们以一个示例代码为例:
const fetchData = async () => {
try {
const res = await fetch('https://www.example.com/api/data');
const data = await res.json();
return data;
} catch (err) {
console.log('error', err);
}
};
上面这段代码是众所周知的一种处理方式。然而,注意到其实我们不太关注代码的正常逻辑路径,而是“error”下有什么可能性
我们可以手写一个错误处理函数来达到与try/catch相同的功能。下面是一个示例:
const fetchData = async () => {
const [err, res] = await to(fetch('https://www.example.com/api/data'));
if (err) return console.log('error', err);
const data = await res.json();
return data;
};
如示例所示,await-to-js库提供了另一种针对promise错误处理的解决方案,尽管只是一种语法糖,但却让代码更简洁易懂。在上述调用中,我们把await提前到第一行,然后用方括号收集错误和数据变量 [err, res]。在第二行,我们关注了err变量。可以理解为把promise调用的错误和数据分开了,并存储了它们,这与在try块中拆分各个异步条件很相似。
二、await-to-js的特点
1、错误处理
与try/catch相比,await-to-js更加方便地获取错误:
const exampleFn = async () => {
const [err, data] = await to(fetchData());
if (err) console.log(err);
else console.log(data);
};
在这个示例中,我们获得了fetchData()返回的数据与可能存在的错误。我们可以在对err进行监听时更加灵活,以便其他处理和更好的错误处理。
2、提供了一个短小的解决方案:
有时候,你所需的解决方案可能如此简单,以至于你不希望使用繁琐的promise和catch块。例如,我们想转换一个promise,以便我们可以将其置于更深的嵌套中:
const namePromise = Promise.resolve({ name: "await-to-js" });
const [err, name] = await to(namePromise.then(data => data.name));
// or useEffect(() => {
// Promise.reject("error example")
// .catch(err => [err])
// .then(([err]) => console.log(err));
// }, []);
在使用它来解决我们的嵌套问题时,这个可怜的Promise.slide(Promise.resolve,Promise.reject)有点不充分,我们可能会尝试做更多的代码以解决这个问题。但使用to,就能够获得更短的代码和更好的可读性。
三、await-to-js的使用示例
1、组合代码
await-to-js通常在以下代码中使用:
const [err, data] = await to(myAsyncFunction());
这完全就是ASYNC/AWAIT的情况下使用的一种解决方案,它会捕获错误,以便我们能够更好地了解问题。然而,在这段与普通的await语法一样的代码代码组合中,我们多了一个易于使用的解决方案。
2、通过async/await调用回调函数
在React。我们很可能需要使用回调函数。然而,在React和其他组件中使用回调函数有时会带来一些问题。特别是在异步调用中,我们必须仔细处理回调函数。await-to-js library提供了一个解决方案:
const getUser = async (userId, callback) => {
const [err, data] = await to(fetchUser(userId));
if (err) return callback(err);
callback(null, data);
};
getUser(123, (err, data) => {
if (err) console.log(err);
else console.log(data);
});
在这个例子中,我们成功地调用了一个异步调用,并使用回调函数检查了异步返回值。
3、等待多个Promise解决
我们有时会有多个异步操作,而不只是一个简单的操作,例如,当我们使用fetch.js从不同URL获取数据时。如果我们想让fetch完成异步操作后,再做其他事情。通过使用Promise.all,我们可以达到这个目的。
const [postErr, postData] = await to(axios.get(`/posts`));
const [userErr, userData] = await to(axios.get(`/users`));
if (postErr || userErr) {
// handle errors
} else {
// handle data
}
Promise.all很有用,但是如果我们只需要其中一个Promise解决就可以了,await-to-js是一个很好的选择,尤其是在我们对代码长度有要求时,因为我们不会像使用Promise.all那样需要创建一个新的Promise。
总结
await-to-js拓展了JavaScript的异步功能,使得原本复杂的异步操作变得简单易懂——任何代码只需一行,获得更好的可读性、可组合参数,并更灵活地进行错误处理。await-to-js的使用方式也相当灵活,可以通过组合、回调函数、等待Promise解决等方式,让您可以更加愉快地使用它。相信在了解并学会使用await-to-js后,您会发现JavaScript异步操作变得更高效,这无疑是前端开发人员应该拥有的解决方案之一。