众所周知 await
可以帮我省略一些无聊的 .then
代码,但是这玩意没有自带.catch
功能。
如果不用 await
的话,我们直接可以Promise.catch
捕获错误,不用写try catch
。
// let result = { success: true, data: [] };
let result = { success: false, error:'something went wrong' };
new Promise((resolve, reject) => {
if (result.success) {
resolve(result.data);
}
reject(new Error(result.error));
})
.then((data) => console.log(data))
.catch((err) => console.log(err));
但是await并没有.catch
的功能!
在没有错误的时候,我们直接使用toplevel的await
获取数据直接爽死。
let result = { success: true, data: [] };
let promise = new Promise((resolve, reject) => {
if (result.success) {
resolve(result.data);
}
reject(new Error(result.error));
});
const data = await promise;
console.log(data)
但是存在错误的时候,我们就必须用 try catch
。
let result = { success: false, error: "something went wrong" };
let promise = new Promise((resolve, reject) => {
if (result.success) {
resolve(result.data);
}
reject(new Error(result.error));
});
try {
const data = await promise;
} catch (err) {
console.log(err);
}
当只有一个await时,我们写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);
}
这时候,2位伟大的天才就想出一个很简单的解决方法,就几行代码,就让我们不用写 try catch
代码块了。
他就是十分巧妙地使用了promise自带的catch功能!
// to.js
export default function to(promise) {
return promise.then(data => {
return [null, data];
})
.catch(err => [err]);
}
export default to;
如果我们想要给catch传递传递给多的错误信息,代码就长这个样子:
/**
* @param { Promise } promise
* @param { Object= } errorExt - Additional Information you can pass to the err object
* @return { Promise }
*/
function to(promise, errorExt) {
return promise
.then(function (data) { return [null, data]; })
.catch(function (err) {
if (errorExt) {
Object.assign(err, errorExt);
}
return [err, undefined];
});
}
export default to;
想要使用这个玩意,也很简单:
import { to } from "await-to-js";
let result = { success: true, data: [] };
// let result = { success: false, error: "something went wrong" };
let promise = new Promise((resolve, reject) => {
if (result.success) {
resolve(result.data);
}
reject(new Error(result.error));
});
// 把promise对象作为参数传入to中
const [err, data] = await to(promise);
// 如果是成功获取的,返回的格式是 [null,data]
// 如果是失败获取 返回的格式是[err,undefined]
if (err) console.log(err)
else{
console.log(data)
}
总之,这个作者的想法很巧妙,对js语法的理解也很深刻。