我正在使用基于cron的调度程序来命中外部api,每2分钟给我一个json数据。我将数据写入文件然后读取它,清理数据并将其添加到mongodb中的集合中。它第一次工作正常,但第二次我得到这样的错误: -
C:\smatserver\smatserver\deals.js:74
throw err;
^
SyntaxError: ./files/localdeals.json: Unexpected end of input
at Object.parse (native)
at C:\smatserver\smatserver\node_modules\jsonfile\index.js:31:18
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:380:3)
这是deals.js代码,我在那里点击外部API并保存在文件中并读取它并尝试将其推送到mongodb: -
var schedule=require('node-schedule');
var request=require('request');
var jsonfile = require('jsonfile');
var _=require('underscore');
var LocalDeals=require('./models/localdeal.js');
//run job every 2 minutes
var dataSchedular=schedule.scheduleJob('*/2 * * * *', function(){
var local_deals_file='./files/localdeals.json';
var local_deals_url='http://api.8coupons.com/v1/getdeals?key=API_KEY&mileradius=10&limit=100&orderby=radius';
request({url:local_deals_url,
json:true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
jsonfile.writeFile(local_deals_file, body, {spaces: 2}, function(err) {
console.error(err);
});
console.log('File write success for '+local_deals_file);
//problem area
jsonfile.readFile(local_deals_file, function(err, local_deals_obj) {
//save in mongodb collection
if(err){ //this error gets thrown on 2nd read
throw err;
}
local_deals_obj.forEach(function(local_deal_obj){
var local_deal_filtered=_.pick(local_deal_obj, 'name', 'address', 'storeID','chainID','phone','state','city','ZIP','URL','storeURL',
'dealTitle','dealinfo','expirationDate','postDate','showImageStandardBig','showImageStandardSmall','providerName','DealTypeID','categoryID',
'lat','lon','distance','dealOriginalPrice','dealPrice','dealSavings','dealDiscountPercent');
var new_local_deal=new LocalDeals({
name : local_deal_filtered.name,
address : local_deal_filtered.address,
storeID : local_deal_filtered.storeID,
chainID : local_deal_filtered.chainID,
phone : local_deal_filtered.phone,
state : local_deal_filtered.state,
city : local_deal_filtered.city,
ZIP : local_deal_filtered.ZIP,
URL : local_deal_filtered.URL,
storeURL : local_deal_filtered.storeURL,
dealTitle : local_deal_filtered.dealTitle,
dealinfo : local_deal_filtered.dealinfo,
expirationDate:local_deal_filtered.expirationDate,
postDate : local_deal_filtered.postDate,
showImageStandardBig: local_deal_filtered.showImageStandardBig,
showImageStandardSmall: local_deal_filtered.showImageStandardSmall,
providerName: local_deal_filtered.providerName,
DealTypeID: local_deal_filtered.DealTypeID,
categoryID: local_deal_filtered.categoryID,
lat: local_deal_filtered.lat,
lon: local_deal_filtered.lon,
distance: local_deal_filtered.distance,
dealOriginalPrice: local_deal_filtered.dealOriginalPrice,
dealPrice: local_deal_filtered.dealPrice,
dealSavings: local_deal_filtered.dealSavings,
dealDiscountPercent: local_deal_filtered.dealDiscountPercent
});
LocalDeals.saveLocalDeals(new_local_deal,function(err,deal){
if(err){
throw err;
}else{
//console.log("local deals added to mongodb");
}
});
});
});
}
else{
console.log(error);
}
});
});
module.exports=dataSchedular;
这是我的名为localdeal.js的模型文件: -
var mongoose=require('mongoose');
mongoose.connect('mongodb://localhost/smat');
var db=mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log('Successfully connected to mongodb');
});
var localdealsSchema=mongoose.Schema({
name: {
type: String
},
address:{
type: String
},
storeID:{
type: String
},
chainID:{
type: String
},
phone:{
type: String
},
state:{
type: String
},
city:{
type: String
},
ZIP:{
type: String
},
URL:{
type: String
},
storeURL: {
type: String
},
dealTitle:{
type: String
},
dealinfo:{
type: String
},
expirationDate:{
type: String
},
postDate:{
type: String
},
showImageStandardBig:{
type: String
},
showImageStandardSmall:{
type: String
},
providerName:{
type: String
},
DealTypeID:{
type: Number
},
categoryID:{
type: Number
},
lat:{
type: Number
},
lon:{
type: Number
},
distance:{
type: Number
},
dealOriginalPrice:{
type: Number
},
dealPrice:{
type: Number
},
dealSavings:{
type: Number
},
dealDiscountPercent:{
type: Number
}
});
var LocalDeals=module.exports=mongoose.model('LocalDeals',localdealsSchema);
module.exports.saveLocalDeals=function(newLocalDeals, callback){
newLocalDeals.save(callback);
}
答案 0 :(得分:2)
在这种情况下永远不要使用setTimeout! writeFile返回回调! ^^
只需将readFile放入writeFile回调
即可 jsonfile.writeFile(local_deals_file, body, {spaces: 2}, function(err) {
if(err){
// error case
}
else
{
jsonfile.readFile(local_deals_file, function(err, local_deals_obj) {
if(err){
// error case
}
else
{
// do something
}
});
}
});
但是在阅读文件的同时?您只需解析响应正文:
jsonfile.writeFile(local_deals_file, body, {spaces: 2}, function(err) {
if(err){
// error case
}
else
{
var obj = null;
try
{
obj = JSON.parse(body);
}
catch(err){
obj = null;
}
if(obj === null)
{
// error case
}
else
{
// insert in mongo
}
}
});
答案 1 :(得分:1)
在我正在阅读文件的部分,我需要一个setTimeout,因为它需要一些时间来写入文件。所以这是我的改变: -
setTimeout(function(){
jsonfile.readFile(local_deals_file, function(err, local_deals_obj) {
//the code same as above
})
}, 1000); //waiting a second to read file