Node.js Promise 教程

在之前的教程中,您可能已经看到了用于异步事件的回调函数。但有时,当回调函数开始嵌套时,它可能会变成一场噩梦,程序会变得冗长而复杂。

什么是承诺?

在开始介绍 Promise 之前,我们先来回顾一下 Node.js 中的“回调”函数。我们在前面的章节中已经多次见过这些回调函数,所以让我们快速浏览一下其中的一个。

下面的示例显示了一个代码片段,用于连接到 MongoDB 数据库并对数据库中的某条记录执行更新操作。

Node.js 的 Promise

  1. 在上面的代码中,函数(err,db)的部分被称为匿名函数或回调函数的声明。当 MongoClient 创建与 MongoDB 数据库,一旦连接操作完成,它将返回回调函数。因此从某种意义上说,连接操作发生在后台,完成后,它会调用我们的回调函数。请记住,这是 Node.js 的关键点之一,允许许多操作同时发生,因此不会阻止任何用户执行操作。
  2. 第二个代码块是在实际调用回调函数时执行的。回调函数只会更新我们的 MongoDB 数据库。

那么什么是 Promise?Promise 只是 Node.js 中回调函数的增强。在开发生命周期中,可能会出现需要将多个回调函数嵌套在一起的情况。在某个时间点,这可能会变得有点混乱且难以维护。简而言之,Promise 是对回调的增强,旨在缓解这些问题。

Promise 的基本语法如下所示;

var promise = doSomethingAync()
promise.then(onFulfilled, onRejected)
  • “doSomethingAync” 是执行某种处理的任何回调或异步函数。
  • 这次,在定义回调时,有一个返回的值称为“promise”。
  • 当返回一个承诺时,它可以有 2 个输出。这由“then 子句”定义。操作可以成功,由“onFulfilled”参数表示。或者它可以有错误,由“onRejected”参数表示。

请注意: 因此,promise 的关键方面是返回值。在 Node.js 中使用普通回调时,没有返回值的概念。由于有返回值,我们可以更好地控制如何定义回调函数。

在下一个主题中,我们将看到承诺的一个例子以及它们如何从回调中受益。

回调到承诺

现在让我们看一个例子,看看如何在 Node.js 应用程序中使用“promises”。为了在 Node.js 应用程序中使用 promise,必须先下载并安装“promise”模块。

然后,我们将修改我们的代码,如下所示,使用承诺更新“Employee”集合中的Employeename。

步骤1) 安装 NPM 模块

要在 Node JS 应用程序中使用 Promises,需要使用 promise 模块。要安装 promise 模块,请运行以下命令

npm 安装承诺

步骤2) 修改代码以包含承诺

回调到 Promise

var Promise = require('promise');
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost/EmployeeDB';

MongoClient.connect(url)
    .then(function(err, db) {
        db.collection('Employee').updateOne({
            "EmployeeName": "Martin"
        }, {
            $set: {
                "EmployeeName": "Mohan"
            }
        });
    }); 

代码说明:-

  1. 第一部分是包含“promise”模块,它将允许我们在代码中使用promise功能。
  2. 现在,我们可以将“then”函数附加到 MongoClient.connect 函数中。它的作用是,当与数据库建立连接时,我们需要执行随后定义的代码片段。
  3. 最后,我们定义代码片段,将员工的 EmployeeName 从姓名“Martin”更新为“Mohan”。

注: -

如果你现在检查你的 MongoDB 数据库中,你会发现如果存在员工姓名为“Martin”的记录,它将被更新为“Mohan”。

要检查数据是否已正确插入数据库,需要执行以下命令 MongoDB

  1. 使用 EmployeeDB
  2. db.Employee.find({员工姓名:Mohan})

第一条语句确保您已连接到 EmployeeDb 数据库。第二条语句搜索员工姓名为“Mohan”的记录。

处理嵌套的承诺

在定义 Promise 时,需要注意的是,“then”方法本身返回一个 Promise。因此从某种意义上来说,Promise 可以相互嵌套或链接。

在下面的例子中,我们使用链接来定义 2 个回调函数,它们都将一条记录插入到 MongoDB 数据库。

(备注:链接是一种用于将方法的执行相互链接起来的概念。假设您的应用程序有两个方法,分别称为“方法 A”和“方法 B”。并且逻辑是“方法 B”应该在“方法 A”之后调用,那么您可以以这样的方式链接执行,即“方法 B”在“方法 A”之后直接被调用。)

本例中要注意的关键一点是,通过使用嵌套承诺,代码变得更清晰、更易读、更易于维护。

处理嵌套的 Promise

var Promise = require('promise');
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost/EmployeeDB';
MongoClient.connect(url)

.then(function(db) {
    db.collection('Employee').insertOne({
        Employeeid: 4,
        EmployeeName: "NewEmployee"
    })

    .then(function(db1) {
        db1.collection('Employee').insertOne({
            Employeeid: 5,
            EmployeeName: "NewEmployee1"
        })
    })
});

代码说明:-

  1. 我们现在定义 2 个“then”子句,它们一个接一个地执行。在第一个 then 子句中,我们传递包含数据库连接的“db”参数。然后我们使用“db”连接的 collection 属性将记录插入“Employee”集合。“insertOne”方法用于将实际文档插入 Employee 集合。
  2. 然后我们使用 2nd then 子句还将另一条记录插入数据库。

如果你现在检查你的 MongoDB 数据库中,你会发现有 2 条记录插入到 MongoDB 数据库。

创建自定义承诺

可以使用名为“q”的节点模块创建自定义承诺。需要使用节点包管理器下载并安装“q”库。使用“q”库后,可以调用方法“denodeify”,这将使任何函数成为返回承诺的函数。

在下面的示例中,我们将创建一个名为“Add”的简单函数,它将添加 2 个数字。我们将此函数转换为返回承诺的函数。

完成后,我们将使用 Add 函数返回的承诺在 console.log 中显示一条消息。

让我们按照以下步骤创建自定义函数来返回承诺。

步骤1) 安装 NPM 模块

要在 Node JS 应用程序中使用“q”,需要“q”模块。要安装“q”模块,请运行以下命令

npm 安装 q

步骤2) 定义以下用于创建自定义承诺的代码。

创建自定义承诺

代码说明:-

  1. 第一步是使用 require 关键字包含“q”库。通过使用此库,我们将能够定义任何函数来返回回调。
  2. 我们正在创建一个名为 Add 的函数,它将添加变量 a 和 b 中定义的 2 个数字。这些值的总和将存储在变量 c 中。
  3. 然后我们使用 q 库来去节点化(将任何函数转换为返回承诺的函数的方法)我们的 Add 函数或者以其他方式将我们的 Add 函数转换为返回承诺的函数。
  4. 我们现在调用“Add”函数,并且能够获得返回的承诺值,因为我们执行了对 Add 函数进行去节点化的步骤。
  5. 'then' 关键字用于指定如果函数执行成功,则在 console.log 中显示字符串“Addition function done”。

运行上述代码时,console.log中将显示输出“Addition function done”,如下所示。

创建自定义承诺

结语

  • 在 Node.js 中使用回调函数确实有它的缺点,有时候在开发过程中,回调函数的嵌套使用会让代码变得比较混乱,难以维护。
  • 嵌套回调函数的大多数问题都可以通过使用 Promise 和生成器来缓解 的node.js
  • Promise 是异步函数返回的一个值,用于指示异步函数执行的处理完成。
  • 当一个异步函数需要在另一个异步函数之后调用时,Promise 可以相互嵌套,以使代码看起来更好,更易于维护