本文介绍 Node.js 7.6 版本默认支持的 async/await 语法,旨在解决传统回调函数导致的代码可读性差及“回调地狱”问题。通过结合 ES6 Promise,详细讲解 async 函数定义、await 等待机制、错误捕获及循环中的应用,并展示在文章详情页数据加载场景下的综合实战代码。
Node.js 异步编程背景与 async/await 引入
以编写文章详情页面为例,典型的数据加载流程包括:首先更新文章的浏览量(PV),接着读取文章详情数据,随后根据文章 ID 查询对应的评论列表及作者信息。在所有数据获取完成后,再执行页面渲染。由于数据库操作均为异步执行,若采用传统的逐层嵌套回调函数方式,代码结构将变得极其混乱且难以维护。随着逻辑层级增加,维护成本显著上升。为解决这一异步操作难题,业界曾推出 async、q、bluebird、co 等多种方案,各有优劣。值得注意的是,Node.js 7.6 版本已默认支持 ES7 的 async/await 语法,配合 ES6 的 Promise 对象使用,可显著提升异步代码的可读性与开发效率。
Async/await 的核心优势在于能够有效避免“回调地狱”(callback hell)带来的代码嵌套过深问题。
async/await 基本概念
基本概念解析:
async 关键字用于声明一个异步函数,await 语法仅能在 async 函数内部使用。
await 关键字用于等待 Promise 对象返回结果,只有当结果返回后,后续代码才会继续执行。
await 后面通常跟随一个 Promise 对象;虽然也可以跟随其他类型的返回值,但那样便失去了使用 await 的意义。
async/await 核心用法示例
具体示例说明:
获取返回值的方式:
var sleep = function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
// 返回 ‘ok'
resolve('ok');
}, time);
})
};
var start = async function () {
let result = await sleep(3000);
console.log(result); // 收到 ‘ok'
};
错误捕获机制:
var sleep = function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
// 模拟出错了,返回 ‘error'
reject('error');
}, time);
})
};
var start = async function () {
try {
console.log('start');
await sleep(3000); // 这里得到了一个返回错误
// 所以以下代码不会被执行了
console.log('end');
} catch (err) {
console.log(err); // 这里捕捉到错误 `error`
}
};
循环中的异步处理
在循环结构中的应用:
var start = async function () {
for (var i = 1; i <= 10; i++) {
console.log(`当前是第${i}次等待..`);
await sleep(1000);
}
};
在循环中使用 await 无需额外使用闭包,且每次循环迭代都会发生阻塞等待。
文章详情页数据加载实战
前文提到的文章详情页场景(综合应用示例):
var showArticle = async function () {
await new Promise(function (resolve, reject) {
PostModel.incPv(postId, function (result) {
resolve(result);
});
});// pv 加 1
var post = await new Promise(function (resolve, reject) {
PostModel.getPostById(postId, function (article) {
resolve(article);
});
});// 获取文章信息
await new Promise(function (resolve, reject) {
userModel.getUserById(post.author,function (author) {
post.author=author;
resolve();
})
});//获取文章作者
var comments = await new Promise(function (resolve, reject) {
CommentModel.getComments(post._id, function (comment) {
resolve(comment);
});
});// 获取该文章所有留言
for(var i=0;i<comments.length;i++){
await new Promise(function (resolve, reject) {
userModel.getUserById(comments[i].author,function (author) {
comments[i].author=author;
resolve();
})
});//获取文章留言作者
}
if (!post) {
req.session.error = '该文章不存在';
return res.redirect('/post');
}
res.render('post',{post: post, comments: comments});
};
showArticle();
以上介绍了 Node.js 中 async/await 与 Promise 的结合使用方法,希望能为解决异步操作问题提供借鉴。如有任何疑问,欢迎留言交流,小编将及时回复。感谢大家对本站的支持!