无法第二次读取json文件:“输入错误意外结束”

时间:2016-08-22 00:42:08

标签: javascript json node.js mongodb

我正在使用基于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);
}

2 个答案:

答案 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