Node.js 7.6+ 异步编程实战:async/await 与 Promise 详解

作者:半夏时间:2026-10-21 23:06:39浏览:376

本文介绍 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 的结合使用方法,希望能为解决异步操作问题提供借鉴。如有任何疑问,欢迎留言交流,小编将及时回复。感谢大家对本站的支持!

作者最新文章