​async/await​​Promises​

回调地狱是一个术语,用于描述 JavaScript 中的以下情况:

function asyncTasks() {
asyncFuncA(function (err, resultA) {
if (err) return cb(err);

asyncFuncB(function (err, resultB) {
if (err) return cb(err);

asyncFuncC(function (err, resultC) {
if (err) return cb(err);

// 更多...
});
});
});
}
​if​​callbackA​​foo​​async​

拯救 Promises

​promises​​ES6​
function asyncTasks(cb) {
asyncFuncA
.then(AsyncFuncB)
.then(AsyncFuncC)
.then(AsyncFuncD)
.then((data) => cb(null, data))
.catch((err) => cb(err));
}
​nodejs​​1​
​promises​
​promises​
​Promise​

async/await

​async/await​
​async/await​
async function asyncTasks(cb) {
const user = await UserModel.findById(1);
if (!user) return cb("用户未找到");

const savedTask = await TaskModel({ userId: user.id, name: "DevPoint" });

if (user.notificationsEnabled) {
await NotificationService.sendNotification(user.id, "任务已创建");
}

if (savedTask.assignedUser.id !== user.id) {
await NotificationService.sendNotification(
savedTask.assignedUser.id,
"任务已为您创建"
);
}

cb(null, savedTask);
}

上面的代码看起来干净多了,但是错误处理还是存在不足。

​promise​​async​​Promise​​Promise​​Promise​​catch​
​async/await​​try/catch​
​try/catch​
async function asyncTasks(cb) {
try {
const user = await UserModel.findById(1);
if (!user) return cb("用户未找到");
} catch (error) {
return cb("程序异常:可能是数据库问题");
}

try {
const savedTask = await TaskModel({
userId: user.id,
name: "DevPoint",
});
} catch (error) {
return cb("程序异常:任务保存失败");
}

if (user.notificationsEnabled) {
try {
await NotificationService.sendNotification(user.id, "任务已创建");
} catch (error) {
return cb("程序异常:sendNotification 失败");
}
}

if (savedTask.assignedUser.id !== user.id) {
try {
await NotificationService.sendNotification(
savedTask.assignedUser.id,
"任务已为您创建"
);
} catch (error) {
return cb("程序异常:sendNotification 失败");
}
}

cb(null, savedTask);
}
​try/catch​
​try/catch​

在 Go 中的处理方式如下:

data, err := db.Query("SELECT ...")
if err != nil { return err }
​try/catch​
​await​​try/catch​​catch​
​await​​resolve​​promise​
function to(promise) {
return promise
.then((data) => {
return [null, data];
})
.catch((err) => [err]);
}
​promise​
function to(promise) {
return promise
.then((data) => {
return [null, data];
})
.catch((err) => [err]);
}

async function asyncTask() {
let err, user, savedTask;

[err, user] = await to(UserModel.findById(1));
if (!user) throw new CustomerError("用户未找到");

[err, savedTask] = await to(
TaskModel({ userId: user.id, name: "DevPoint" })
);
if (err) throw new CustomError("程序异常:任务保存失败");

if (user.notificationsEnabled) {
const [err] = await to(
NotificationService.sendNotification(user.id, "任务已创建")
);
if (err) console.error("程序异常");
}
}
​to​

总结

​async/await​​try/catch​