如何在写await async的时候不用try catch
在js的日常使用中,异步操作是经常会用到的,promise 和 await/async可以避免会掉地狱的痛苦。
我们可以用promise的链式回调处理异步结果,但是当有多个异步需要处理的时候也会避免不了要用一串的then函数来处理
function asyncTask(cb) {
asyncFuncA.then(AsyncFuncB)
.then(AsyncFuncC)
.then(AsyncFuncD)
.then(data => cb(null, data)
.catch(err => cb(err));
}
这个时候可以用await/async来处理多个异步调用的情况
async function asyncTask(cb) {
const user = await UserModel.findById(1);
if(!user) return cb('No user found');
const savedTask = await TaskModel({userId: user.id, name: 'Demo Task'});
if(user.notificationsEnabled) {
await NotificationService.sendNotification(user.id, 'Task Created');
}
if(savedTask.assignedUser.id !== user.id) {
await NotificationService.sendNotification(savedTask.assignedUser.id, 'Task was created for you');
}
cb(null, savedTask);
}
这样看的话异步可以像同步那样处理很简洁易读,但是错误的捕获却做不到,这里需要用到try/catch来做错误的处理
async function asyncTask(cb) {
try {
const user = await UserModel.findById(1);
if(!user) return cb('No user found');
} catch(e) {
return cb('Unexpected error occurred');
}
try {
const savedTask = await TaskModel({userId: user.id, name: 'Demo Task'});
} catch(e) {
return cb('Error occurred while saving task');
}
if(user.notificationsEnabled) {
try {
await NotificationService.sendNotification(user.id, 'Task Created');
} catch(e) {
return cb('Error while sending notification');
}
}
if(savedTask.assignedUser.id !== user.id) {
try {
await NotificationService.sendNotification(savedTask.assignedUser.id, 'Task was created for you');
} catch(e) {
return cb('Error while sending notification');
}
}
cb(null, savedTask);
}
所以就成了上面这样,这样看来代码量和简洁程度都不是很友好,为了能够使异步可以像写同步一样易于理解,以及代码尽量简单减少嵌套,可以考虑封装一种函数拥有promise的便捷错误处理和await/async的简洁的写法,因为await 后面本来就是一个promise所以我们直接可以先处理promise 用catch来捕获error,在返回一个promise 交给await处理。
export default function to(promise) {
return promise.then(data => {
return [null, data];
})
.catch(err => [err]);
}
下面我们来测试一下这个方法的可行性
function taskPromise(status) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (status === "fail") {
return reject("error")
} else {
return resolve("success")
}
}, 1000)
})
}
async function asyncTasks() {
let err, result
[err, result] = await to(taskPromise(""))
if (err) {
console.log("it‘s error")
} else {
console.log("it‘s" + result)
}
[err, result] = await to(taskPromise("fail"))
if (err) {
console.log("it‘s error")
} else {
console.log("it‘s" + result)
}
}
asyncTasks() //it‘ssuccess it‘s error