await-to-js
本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与。
promise和async await
在es6出现之前,对于异步的操作主要通过回调函数形式实现.如jquery在数据请求上的封装
$.get(url1,() => {
$.get(url2,() => {
$.get(url3,() => {
$.get(url4,() => {})
})
})
})
es6后引入了promise,可以让上述代码更加优雅实现,可以通过then来实现链式调用。catch来捕获错误
axios.get(url1)
.then(() => axios.get(url2))
.then(() => axios.get(url3))
.then(() => axios.get(url4))
.catch((err) => {
console.log(err)
})
es7引入了async await来使异步代码看起来更像同步,但是async对于错误的捕获需要使用trycatch或者在await的promise后面增加catch的捕获
async function test() {
const value1 = await axios.get(url1)
const value2 = await axios.get(url2)
const value3 = await axios.get(url3)
const value4 = await axios.get(url4)
}
await-to-js
那么有什么办法可以不用每次在写async函数不写trycatch呢?
这边已经有人帮我们造好轮子了,具体用法如下
npm i await-to-js --save
import to from 'await-to-js';
// If you use CommonJS (i.e NodeJS environment), it should be:
// const to = require('await-to-js').default;
async function asyncTaskWithCb(cb) {
let err, user, savedTask, notification;
[ err, user ] = await to(UserModel.findById(1));
if(!user) return cb('No user found');
[ err, savedTask ] = await to(TaskModel({userId: user.id, name: 'Demo Task'}));
if(err) return cb('Error occurred while saving task');
if(user.notificationsEnabled) {
[ err ] = await to(NotificationService.sendNotification(user.id, 'Task Created'));
if(err) return cb('Error while sending notification');
}
if(savedTask.assignedUser.id !== user.id) {
[ err, notification ] = await to(NotificationService.sendNotification(savedTask.assignedUser.id, 'Task was created for you'));
if(err) return cb('Error while sending notification');
}
cb(null, savedTask);
}
async function asyncFunctionWithThrow() {
const [err, user] = await to(UserModel.findById(1));
if (!user) throw new Error('User not found');
}
此函数和await连用返回一个错误信息和成功的数据。那么具体这个是怎么实现的。
源码实现
具体实现不难,通过封装了一层,把cathch和then来实现,这样在async函数中,不会因为一个错误导致整个函数中断执行
export function to(promise, errorExt) {
return promise
.then((data) => [null, data])
.catch((err) => {
if (errorExt) {
const parseError = Object.assign({}, err, errorExt);
return [parseError, undefined];
}
return [err, undefined];
});
}
结束语
通过阅读await-to-js
这个库,学习了如何不使用trycatch来实现错误的捕获