我是JS的新手,我现在陷入困境。我想在开始一个新查询之前清除我的数据库,并且它在collection.find命令中一直停滞不前。如果我删除代码以清除数据库,一切正常。
router.get('/parse', function(req, res) {
collection.remove({})
collectionweb.remove({})
collectionhit.remove({})
//Converter Class
var Converter = require("csvtojson").core.Converter;
var fs = require("fs");
var csvFileName = "./download/company.csv";
var fileStream = fs.createReadStream(csvFileName);
//new converter instance
var param = {};
var csvConverter = new Converter(param);
request({
uri: "http://online.barrons.com/news/articles/SB50001424053111904537004580085820431503044?mod=BOL_twm_fs",
}, function(error, response, body) {
collectionweb.insert({
"website": body
});
});
//end_parsed will be emitted once parsing finished
csvConverter.on("end_parsed", function(jsonObj) {
//Insert into DB
collection.insert(jsonObj);
});
fileStream.pipe(csvConverter);
collectionweb.find({}, function(e, docs1) {
for (var j in docs1) {
var body = docs1[j]
var webs = body.website
console.log(1)
collection.find({}, function(e, docs) {
for (var i in docs) {
console.log(2)
var companies = docs[i]
var Score = 0;
$words = webs.search(companies.Symbol);
console.log(3)
if ($words > 0) {
StockScore++console.log(Score)
collectionhit.insert(companies)
collectionhit.update({
"Name": companies.Name
}, {
'$set': {
"score": Score
}
})
} else {};
};
});
};
});
});
答案 0 :(得分:2)
有一些问题,但它们有一个共同点:你还没有理解Node.js是异步的。只是google" node.js异步"并且您将获得一些资源,或者只是在SO上查找(例如How do I get started with Node.js?)。
它的主旨是等待回调或事件,例如:
var eiot = new EventedIOThing('paaarammm');
// use once, unless you for sure need to listen for the event multiple times
eiot.once('open',function onEIOTOpen() {
console.log('opened the thing.');
}).once('error',function onEIOTError(err) {
console.warn('there were problemzzz');
}).once('end',function onEIOTEnd() {
// successfully finished evented IO thing...
someAction(this.dep,'anotherparam',function callMeWhenActionIsDone(err,result) {
if ( err ) {
console.warn('someAction had a problem!',err);
return; // exit early if we didn't get an optimal result
}
anotherDependentAction(result,function callMeWhenSecondActionIsDone(err,result) {
if ( err ) { // this 'err' is local to this function's scope
console.warn('anotherDependentAction had a problem!',err);
return; // exit early again
}
console.log('All done... what do you want to do next?');
});
});
});
鉴于变量/函数名称和注释,上面的代码非常自我解释,但要密切关注方法的调用方式,最重要的是何时调用。事情不是连续发生的,而是代码开启了#34;备用"直到成功结果发生依赖/正确的事情,然后程序流才会继续。
上述编码风格的缺点是,您最终会深入获得许多嵌套函数。这就是像async这样的lib发挥作用的地方。它允许浅层函数程序流:你指定一个函数数组,并在内部调用回调函数时使用异步句柄,你只需要担心序列。
现在,使用您目前拥有的代码,我们从第一个示例中学到的内容,以及通过引入异步模块进行的操作,可以按如下方式重写:
var async = require('async'), // https://github.com/caolan/async
fs = require('fs'),
Converter = require('csvtojson').core.Converter;
router.get('/parse',function cbGetParse(req, res) {
async.series([
collection.remove.bind(collection),
collectionweb.remove.bind(collectionweb),
collectionhit.remove.bind(collectionhit),
function convertCsv(callback) {
var cbCalled = false; // i don't trust csvtojson to handle errors properly
fs.createReadStream('./download/company.csv')
.once('error',function(err) {
if ( !cbCalled ) {
cbCalled = true;
callback(err,null);
}
})
.pipe(new Converter({})) // pipe returns an instance of the Converter object
.once('end_parsed',function onConverterEnd(jsonObj) {
collection.insert(jsonObj,function cbCollInsert(err,result) {
if ( !cbCalled ) {
cbCalled = true;
callback(err,result);
}
});
});
},
function barronsHttpRequest(callback) {
request({
uri: 'http://online.barrons.com/news/articles/SB50001424053111904537004580085820431503044?mod=BOL_twm_fs',
},function cbRequest(err,response,body) {
if ( err ) {
callback(err,null);
return; // if err, exit early
}
collectionweb.insert({'website':body},function cbCollWebInsert(err,result) {
callback(err,result);
});
});
},
function lastChunkOfCode(callback) {
// not going to rewrite this, same principle applies as above
collectionweb.find({}, function(e, docs1) {
for (var j in docs1) {
var body = docs1[j]
var webs = body.website
console.log(1)
collection.find({}, function(e, docs) {
for (var i in docs) {
console.log(2)
var companies = docs[i]
var Score = 0;
$words = webs.search(companies.Symbol);
console.log(3)
if ($words > 0) {
StockScore++console.log(Score)
collectionhit.insert(companies)
collectionhit.update({
"Name": companies.Name
}, {
'$set': {
"score": Score
}
})
} else {};
};
});
};
callback();
});
}
],function asyncComplete(err,result) {
// you don't specify how to respond to the request so...
if ( err ) {
console.warn('Problem with /parse:',err);
}
res.end();
});
});
我对你的脚本应该如何工作的假设做了一个 crap-ton ,所以它可能不是你想要的100%,但是已经应用了异步概念。另外,我没有测试这段代码。您需要确定哪些可以并行运行vs系列,您的控制流应该是什么样的以及您希望如何处理错误(错误确实发生)。
请注意,我没有在脚本的最后一块中实现异步行为,因为我无法弄清楚你的收藏关系是什么 - 而且我不会为你完成所有的工作。我注意到它可以进行一些优化。我没有理由从两个集合中选择所有文档。您需要将选择器/查询处理卸载到数据库中,如果您可以帮助它,它不应该在您的应用程序中。
一些外卖:
Collection.remove
(doc)接受回调,使用它。Collection.insert
(doc)相同 - 即使文档说回调是可选的,也只应在非常罕见的情况下省略。 (如果你是否正在使用写关注,我也不在乎。)for...in
,尤其是对于数组,请使用普通for
或Array.forEach
for
循环与任何异步调用 - 特别是与套接字相关时,即MongoDb - 你需要耐心等待回调,否则你会淹没套接字(如拒绝服务攻击)。我建议使用async.eachSeries
或async.eachLimit
"
或'
,他们会做同样的事情,不要混用它们。