【发布时间】: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