📜  Node.js 中的承诺

📅  最后修改于: 2022-05-13 01:56:27.690000             🧑  作者: Mango

Node.js 中的承诺

简介:回调函数用于异步事件。每当必须发生任何异步事件时,通常首选使用回调(如果数据不是嵌套的或相互依赖的)。

下面是最简单的例子,我们可以想象如何使用回调:-

例子:

javascript
module.exports = (x, callback) => {
    if (x <= 0)
        setTimeout(() =>
            callback(new Error("Square dimensions
            should be greater than zero: s = " + x),
            null), 2000);
    else
        setTimeout(() =>
            callback(null, {
                perimeter: () => (4*(x)),
                area:() => (x*x)
            }), 2000);
}


javascript
dboper.insertDocument(db, { name: "Test", description: "Test"},
    "test", (result) => {
        console.log("Insert Document:\n", result.ops);
 
        dboper.findDocuments(db, "test", (docs) => {
            console.log("Found Documents:\n", docs);
 
            dboper.updateDocument(db, { name: "Test" },
                { description: "Updated Test" }, "test",
                (result) => {
                    console.log("Updated Document:\n", result.result);
 
                    dboper.findDocuments(db, "test", (docs) => {
                        console.log("Found Updated Documents:\n", docs);
                             
                        db.dropCollection("test", (result) => {
                            console.log("Dropped Collection: ", result);
 
                            client.close();
                        });
                    });
                });
        });
    });


javascript
dboper.insertDocument(db,
    { name: "Test", description: "Just a test"},
    "test").then((result) => {
        console.log("Insert Document:\n", result.ops);
    });


javascript
MongoClient.connect(url).then((client) => {
 
    const db = client.db(database_name);
 
    database.insertDocument(db, { name: "Test",
        description: "Chill Out! Its just a test program!"},
        "test")
        .then((result) => {
            return database.findDocuments(db, "test");
        })
        .then((documents) => {
            console.log("Found Documents:\n", documents);
 
            return database.updateDocument(db, { name: "Test" },
                    { description: "Updated Test" }, "test");
        })
        .then((result) => {
            console.log("Updated Documents Found:\n", result.result);
 
            return database.findDocuments(db, "test");
        })
        .then((docs) => {
            console.log("The Updated Documents are:\n", docs);
                             
            return db.dropCollection("test");
        })
        .then((result) => {
             
            return client.close();
        })
        .catch((err) => alert(err));
 
})
.catch((err) => alert(err));


javascript
var aPromise = new Promise(function(resolve, reject) {
    request.get(options, function(err, resp, body) {
        if (err) {
            reject(err);
        } else {
            resolve(JSON.parse(body));
        }
    })
});


什么是承诺? Promise 基本上是 Node.js 中回调的进步。换句话说,promise 是一个 JavaScript 对象,用于处理所有异步数据操作。在开发应用程序时,您可能会遇到使用大量嵌套回调函数的情况。

javascript

dboper.insertDocument(db, { name: "Test", description: "Test"},
    "test", (result) => {
        console.log("Insert Document:\n", result.ops);
 
        dboper.findDocuments(db, "test", (docs) => {
            console.log("Found Documents:\n", docs);
 
            dboper.updateDocument(db, { name: "Test" },
                { description: "Updated Test" }, "test",
                (result) => {
                    console.log("Updated Document:\n", result.result);
 
                    dboper.findDocuments(db, "test", (docs) => {
                        console.log("Found Updated Documents:\n", docs);
                             
                        db.dropCollection("test", (result) => {
                            console.log("Dropped Collection: ", result);
 
                            client.close();
                        });
                    });
                });
        });
    });

这是由于回调函数的嵌套而发生的。现在想象一下,如果你需要像这样执行多个嵌套操作。这会使您的代码变得混乱且非常复杂。在 Node.js 世界中,这个问题被称为“回调地狱” 。为了解决这个问题,我们需要在嵌套时去掉回调函数。这就是 Promise 发挥作用的地方。 Node 中的 Promise 表示将完成或拒绝的操作。在完成的情况下,承诺被遵守,否则,承诺被打破。因此,正如这个词所暗示的那样,要么信守诺言,要么违背诺言。与回调不同,promise 可以被链接。

对 Promises 的回调Promises 通知请求是被满足还是被拒绝。回调可以注册到.then()来处理执行和拒绝。 .then()可以链接以处理履行和拒绝,而.catch()可以用于处理错误(如果有)。

例子:

javascript

dboper.insertDocument(db,
    { name: "Test", description: "Just a test"},
    "test").then((result) => {
        console.log("Insert Document:\n", result.ops);
    });

嵌套 Promises:经常会遇到需要使用嵌套 Promise 的情况。嵌套的 Promise 以.then()开头,在每个.then()中我们都有一个return 语句。在return 语句之后, .then()以相同的方式跟随。以下示例显示了最坏的情况,其中使用多个 .then() 方法来声明嵌套的 Promise(它们相互依赖以执行自己的操作)。

例子:

javascript

MongoClient.connect(url).then((client) => {
 
    const db = client.db(database_name);
 
    database.insertDocument(db, { name: "Test",
        description: "Chill Out! Its just a test program!"},
        "test")
        .then((result) => {
            return database.findDocuments(db, "test");
        })
        .then((documents) => {
            console.log("Found Documents:\n", documents);
 
            return database.updateDocument(db, { name: "Test" },
                    { description: "Updated Test" }, "test");
        })
        .then((result) => {
            console.log("Updated Documents Found:\n", result.result);
 
            return database.findDocuments(db, "test");
        })
        .then((docs) => {
            console.log("The Updated Documents are:\n", docs);
                             
            return db.dropCollection("test");
        })
        .then((result) => {
             
            return client.close();
        })
        .catch((err) => alert(err));
 
})
.catch((err) => alert(err));

现在与使用回调相比,我们的代码看起来比以前干净了很多。由于 .then() 可以链接在一起,因此每个 Promise 在代码中都很容易识别。如果发生错误,则执行 .catch(err)。

创建自定义 Promises您始终可以使用新的构造函数在 Node 中创建自己的自定义 Promises。

以下示例将帮助我们了解如何创建自定义承诺:-

例子:

javascript

var aPromise = new Promise(function(resolve, reject) {
    request.get(options, function(err, resp, body) {
        if (err) {
            reject(err);
        } else {
            resolve(JSON.parse(body));
        }
    })
});