【问题标题】:Trouble with node, mongodb, and promisesnode、mongodb和promise的问题
【发布时间】:2018-02-18 07:45:18
【问题描述】:

我的工作代码使用一系列嵌套回调首先使用 find 命令检查数据库中是否存在预先存在的条目。如果条目存在,则不执行任何操作。如果该条目不存在,则在数据库中插入一个。

这段代码运行良好,但没有提供有意义的错误处理:

var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://localhost/peeps", function(err, db) {
        if(err) {
            if(db) db.close();
            return next();
        }
        var query = { section: req.body.section, year: req.body.year, semester: req.body.semester };
            db.collection("sections").find(query).toArray(function(err, result) {

            if( result.length >= 1  ) {
                db.close();
                if(callback) callback();
            } else {
                var days = [];

                for(var i = 1; i < 6; i++) {

                    if( field['starthour' + i]  != '') {
                        var oneDay = {};
                        oneDay.day = field['day' + i];
                        // more fields being stored here...
                        days.push(oneDay);

                    }
                }

                db.collection("sections").insertOne(
                    { 
                        coursetitle: req.body.course,
                        // more fields being stored here
                        days: days
                    }
                )
                db.close();
                if(callback) callback();
            }
        })
    })

输入承诺,这是回调地狱和错误处理的假定修复。所以我在 promise 上遇到的第一个问题(我已经用关键字 Mongodb、promise、node 和 find 搜索并尝试了每篇文章)是如何仍然避免嵌套 promises。

这是我尝试实施 Promise 策略的许多不同方式中的一种:

var MongoClient = require('mongodb').MongoClient;
    MongoClient.connect("mongodb://localhost/peeps")
        .then(function(db) {
            var query = { section: req.body.section, year: req.body.year, semester: req.body.semester };
            db.collection("sections").find(query).toArray(function(err, result) {
                // I am assuming that returns from this callback won't return to the next .then statement...
                // how to avoid nesting promises?
                // If a nested promise is necessary, how do I set it up?  .find does not seem to return a promise... (I've tried)
                if(err) return err; // Where does it go?  probably not to the catch statement like I want it to :-(
                if(result.length >= 1)
                    return {db: db, preexist: true};
                else {
                    return {db: db, preexist: false};
                }
            })
        })
        .then(function(o){
            // o didn't make it here, so db doesn't exist nor preexist, they're undefined
            console.log(o.db + o.preexist)
            // do the insert one if necessary
        })      
        .catch(function(error) {
            console.log(error.message);
        })

所以本质上我的主要问题是:如何避免嵌套?如果需要嵌套承诺,有没有办法将错误返回到最外层的 .catch?如果未指定回调,.find 是否返回承诺?如果 .find 可以返回一个 Promise,那么将结果存储在数组中的正确语法是什么?

任何帮助将不胜感激。

【问题讨论】:

  • 你的第一个 .then 没有返回值,这就是为什么第二个 then 中的 o 是未定义的
  • 两个选项,将 db.collection("sections").find(query).toArray 代码包装在 Promise 中,或者,如果文档正确,toArray 无论如何都会返回 Promise,所以使用它。但是,当您想要将变量传递到 .then 链中时,总会存在某种程度的嵌套

标签: javascript mongodb callback promise nested


【解决方案1】:

MongoDB 就像大多数其他数据库一样提供者 提供了一种检索最新错误的方法。

对于 MongoDB,您将使用 db.getLastError() 来检索错误对象/文档。 Here are the fields you can use from that document.

从更抽象的角度来看,构建 Promise 的方式取决于数据模型本身、应用程序的逻辑以及可以安全执行的缓存量。

您可以使用 Promise.all 方法和数据库操作集合来实现执行承诺的链接方式,而无需多个 .then() 语句和/ 或不必要的数据库连接:

function updateDatabase (name, token) {
  return MongoClient.connect(MONGODB_URL)
     .then( (db) => 
          Promise.all([
            db.collection('testCollection').update({name}, {$pull: {tokens: {$in: [token]}}}),
            db.collection('log').insert({name, token})
          ]).then(() => db.close(true)
          ).then(`Invalid token: ${token} has been removed from: ${name}`
          ).catch((err) => { db.close(true); throw err }); //catch errors
     )
}

More information in here: from https://stackoverflow.com/a/45845982/1848744

【讨论】:

  • .then(Invalid token: ${token} has been removed from: ${name}) - 不,无效 - 不会中断,但您认为这样做有什么用?
猜你喜欢
  • 2020-12-19
  • 1970-01-01
  • 2017-05-21
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
  • 2016-11-13
  • 2019-03-19
相关资源
最近更新 更多