2016-08-22 1 views
0

Я использую график на основе cron, чтобы попасть в внешний api, который дает мне json-данные каждые 2 минуты. Я записываю данные в файл, а затем читаю их, чищу данные и добавляю их в коллекцию в mongodb. Он отлично работает в первый раз, но второй раз я получаю сообщение об ошибке, как это: -Невозможно прочитать файл json второй раз: «Неожиданный конец ошибки ввода»

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); 
} 

ответ

1

в той части, где я читал файл, мне нужен SetTimeout, потому что это займет некоторое время, чтобы написать к e файл. Итак, вот мое изменение: -

setTimeout(function(){ 
     jsonfile.readFile(local_deals_file, function(err, local_deals_obj) { 
      //the code same as above 

}) 
}, 1000); //waiting a second to read file 
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 
     } 

    } 
}); 
+0

Интересный ответ ... я дам ему попробовать, а затем примите ваш ответ ... но не могли бы вы объяснить мне, почему избежать setTimeout? –

+0

Если вы пишете большой файл, setTimeout может завершиться до конца написания. В этом случае операция чтения может завершиться до конца записи. – Dafuck

+0

Вы были правы, я закончил использовать ваше решение –

Смежные вопросы