Javascript Nodejs,通过回调关闭mongo db连接
我有回调、异步思维等问题 执行程序:Javascript Nodejs,通过回调关闭mongo db连接,javascript,node.js,mongodb,asynchronous,callback,Javascript,Node.js,Mongodb,Asynchronous,Callback,我有回调、异步思维等问题 执行程序: 连接到mongoDb 创建url-+从locArray添加部件 发送get请求(针对每个请求) 将数据保存到mongo db 密切联系 问题: 如果连接在jsonDataFromApi中的最后一行关闭——“服务器实例池被破坏”,然后每个请求的所有数据都保存到数据库中 因此,callback(db)被发送到另一个地方-closeMongoDb 但出现了错误 无法读取未定义的属性“close” 我认为,问题在于异步、发送回调等 const Mong
- 如果连接在jsonDataFromApi中的最后一行关闭——“服务器实例池被破坏”,然后每个请求的所有数据都保存到数据库中
- 因此,
被发送到另一个地方-callback(db)
closeMongoDb
- 但出现了错误 无法读取未定义的属性“close”
const MongoClient = require('mongodb').MongoClient;
const Array = require('node-array');
const request = require('request');
var locationArray = [
'location1',
'location2',
'location3',
'location4'
];
var dataFromLocApi = (loc, callback) => {
request({
url: `https://example.com/${loc}`,
json: true
}, (error, response, body) => {
if (error){
callback('Error connection to url.');
} else{
callback(undefined, body.result);
}
});
};
var jsonDataFromApi = (urldb, callback) => {
MongoClient.connect(urldb, (err, db) => {
if (err) {
console.log('MongoDb connection error.');
}
console.log('MongoDb - connected.');
locationArray.forEachAsync(function(loc, index, arr) {
dataFromLocApi(loc, (errorMessage, results) => {
if (errorMessage) {
console.log(errorMessage);
} else {
console.log(JSON.stringify(results, undefined, 2));
db.collection('testCollection').insert(results, function(error, record) {
if (error)
throw error;
console.log("data saved");
});
}
});
}, function() {
console.log('complete');
});
callback(db);
});
}
var closeMongoDb = (urldb, callback) => {
jsonDataFromApi(urldb, (error, db) => {
if (error){
callback('Close connection - failure');
} else{
db.close();
console.log('MongoDb connections was closed.');
}
});
}
closeMongoDb('mongodb://127.0.0.1:27017/testDb', (err, db) => {
console.log('DONE');
} );
这里肯定存在异步问题。 在调用
db.close()
之前,您没有等待处理项目
此外,您定义的函数的语义也不清楚。例如,函数closeMongoDb
基本上应该关闭数据库,就是这样。但这里还有另一项工作:获取数据,然后关闭数据库
另外,我可能会使用async
模块,而不是节点数组
,因为最后一个模块似乎可以解决其他问题
我已经重构了代码。请阅读我的评论。我尽量把它说清楚
const MongoClient=require(“mongodb”).MongoClient;
常量请求=要求(“请求”);
//我们将使用异步模块
//这是处理异步行为的经典模块。
const async=require(“异步”);
//如您所见,此函数接受回调
//如果连接到数据库时出错
//它通过回调将其传递给调用方(err)
//这是一种普遍模式
const connectToDb=函数(urldb,回调){
MongoClient.connect(urldb,(err,db)=>{
如果(错误){
log(“MongoDb连接错误”);
回调(err);
回来
}
//如果一切正常,将db作为数据传递给调用方。
回调(未定义,db);
});
};
//此方法获取单个位置的数据。
//带有错误/数据的逻辑是完全相同的。
const getData=(loc,callback)=>{
请求(
{
网址:`https://example.com/${loc}`,
json:true
},
(错误、响应、正文)=>{
如果(错误){
回调(“错误连接到url”);
回来
}
回调(未定义,body.result);
}
);
};
//此函数遍历每个位置,提取数据并将其保存到数据库
//最后一个参数是回调,我将其命名为allDataFetchedCb以明确说明这一点
//我们在处理完所有位置后才调用它
//所有内容都保存到数据库中。
const saveDataFromLocations=函数(位置、数据库、allDataFetchedCb){
//这里的第一个参数是一个项目数组
//第二个是我们希望为每个项执行的异步函数
//当处理单个项目时,我们调用回调。我将其命名为“locProcessedCB”
//所以很清楚会发生什么。
//第三个参数是一个回调,当所有项
//已经处理过了。
async.each(
位置,
功能(loc、locProcessedCb){
获取数据(loc,(apiErr,结果)=>{
if(apiErr){
控制台日志(apiErr);
//我们无法处理该项,请将错误传递给我们。
locProcessedCb(apiErr);
回来
}
console.log(
`已从api获取数据:${JSON.stringify(
后果
未定义,
2.
)}`
);
db.collection(“testCollection”).insert(结果、函数(dbError){
if(dbError){
//还有一个错误,我们无法处理该项目。
locProcessedCb(dbError);
回来
}
//确定调用此函数后,项目处理无错误
//所以我们告诉async.each函数:好的,很好,继续处理下一个函数。
locProcessedCb();
});
});
},
功能(err){
//我们会在所有物品处理完毕或发生任何错误后到达这里。
如果(错误){
allDataFetchedCb(错误);
回来
}
log(“所有位置都已处理”);
//好的,把db对象传上去。
allDataFetchedCb(未定义,db);
}
);
};
//此函数是一个入口点。
//它逐个调用上述所有函数。
const getDataAndCloseDb=函数(urldb、位置、回调){
//好吧,让我们连线。
connectToDb(urldb,(err,db)=>{
如果(错误){
回调(err);
回来
}
//现在让我们把所有的东西都准备好。
saveDataFromLocations(位置,数据库,(错误,数据库)=>{
如果(错误){
回调(err);
回来
}
//如果没有db对象,或者没有close方法,我们想知道。
如果(!db | |!db.close){
回调(新错误(“无法关闭数据库连接”);
}
//关闭数据库。
db.close(错误=>{
//如果没有错误,err==未定义或null
//所以这个调用等于回调(未定义);
回调(err);
});
});
});
};
const locationArray=[“location1”、“location2”、“location3”、“location4”];
//最后调用函数,将所有需要的数据传递到内部。
获取数据