我是nodejs的新手。很长一段时间以来,我一直在挠头,为什么下面的代码抛出错误。我在堆栈溢出中发现了一些类似的问题,但无法获得查找错误的帮助。
var albums_coll,photos_coll;
async.waterfall([
function(cb){
MongoClient.connect(url,
(err,dbase)=>{
if(err) {
console.log('bad');
process.exit(-1);
}
console.log("I have a connection!");
db=dbase;
cb(null);
}
);
},
function(cb){
db.collection("albums",cb);
},
function(album_obj,cb){
albums_coll = album_obj;
db.collection("photos",cb);
},
function(photos_obj,cb){
photos_coll = photos_obj;
cb(null);
},
function(cb){
albums_coll.InsertOne(a1,cb);
},
function(inserted_doc,cb){
console.log("I have Inserted a document!!");
console.log(inserted_doc);
cb(null);
}
],
function(err,results){
console.log("Done!!!");
console.log(err);
console.log(results);
db.close();
});
请指教!!
以下是其显示的错误。
I have a connection!
C:UsersthathineNodeLiveChapter08mongotestnode_modulesmongodblibmongo_client.js:433
throw err
^
Error: Callback was already called.
at C:UsersthathineNodeLiveChapter08mongotestnode_modulesasyncdistasync.js:903:32
at Db.collection (C:UsersthathineNodeLiveChapter08mongotestnode_modulesmongodblibdb.js:466:27)
.
.
.
您传递给db.collection()
函数的callback()
函数被调用了两次。第一次发生这种情况是在MongoDB 库内调用db.collection()
时。它发生在以下块中 - 我添加了一个指向第466 行的注释,如堆栈所示:
if(options == null || !options.strict) {
try {
var collection = new Collection(this, this.s.topology, this.s.databaseName, name, this.s.pkFactory, options);
if(callback) callback(null, collection);
return collection;
} catch(err) {
// if(err instanceof MongoError && callback) return callback(err);
if(callback) return callback(err); // <-- Line 466 - first time callback is called
throw err;
}
}
第二次调用它是由异步库调用的,当它需要确定它是否必须执行数组中的下一个任务或调用最终回调时;到那时,回调已经为空。您看到的错误是在异步库中的onlyOnce()
函数中引发的:
function onlyOnce(fn) {
return function() {
if (fn === null) throw new Error("Callback was already called.");
var callFn = fn;
fn = null;
callFn.apply(this, arguments);
};
}
因此,以下代码将引发错误:
async.waterfall([
function(callback) {
MongoClient.connect('mongodb://localhost:27017/test', (error, db) => {
if (error) {
console.error(error);
process.exit(-1);
}
callback(null, db);
});
},
function(db, callback) {
console.log('Querying albums collection...');
// This will cause the exception
db.collection('albums', callback);
},
function(db, albums, callback) {
console.log('Got albums...');
console.log('Querying photos collection...');
db.collection('photos', (error, photos) => {
if (error) {
return callback(error);
}
callback(null, db, albums, photos);
});
},
function(db, albums, photos, callback) {
console.log('Got photos...');
callback(null, 'DONE');
}
], function (error, results) {
console.error(error);
console.log(results);
process.exit(0);
});
虽然此版本的代码将按预期执行:
async.waterfall([
function(callback) {
MongoClient.connect('mongodb://localhost:27017/test', (error, db) => {
if (error) {
console.error(error);
process.exit(-1);
}
callback(null, db);
});
},
function(db, callback) {
console.log('Querying albums collection...');
db.collection('albums', (error, albums) => {
if (error) {
return callback(error);
}
callback(null, db, albums);
});
},
function(db, albums, callback) {
console.log('Got albums...');
console.log('Querying photos collection...');
db.collection('photos', (error, photos) => {
if (error) {
return callback(error);
}
callback(null, db, albums, photos);
});
},
function(db, albums, photos, callback) {
console.log('Got photos...');
callback(null, 'DONE');
}
], function (error, results) {
console.error(error);
console.log(results);
process.exit(0);
});
/* Output:
Querying albums collection...
Got albums...
Querying photos collection...
Got photos...
null
DONE
*/
希望这有帮助!