2017-08-31 4 views
2

J'ai écrit une API web scraping basée sur NodeJS, en utilisant Cheerio, node-fetch et fs-extra. Dans la partie de code suivante, j'appelle la méthode getReport, pour chaque chaîne du tableau config.supportedMountains. Pour chacun des éléments, je veux les faire passer par la fonction fetchAndStore, ce qui rend la requête html, l'exécute à travers l'analyseur spécifique, puis stocke les résultats JSON.Données d'une exécution asynchrone d'une fonction en cours de mixage avec une autre exécution de la fonction

// const fs = require('fs-extra'); 
 
const _ = require('lodash'); 
 
// const Promise = require('promise'); 
 
const schedule = require('node-schedule'); 
 

 
const fetchAndStore = require('./fetchAndStore.js'); 
 

 
const config = require('../config.js'); 
 

 
exports.run = function() { 
 
    schedule.scheduleJob('*/20 * * * * *', function() { 
 
    // Get the most recent reports 
 
    // And write them to storage 
 
    _.forEach(config.supportedMountains, function(fName) { 
 
     getReport(fName); 
 
    }); 
 
    }); 
 
}; 
 

 
/** 
 
* Gets the lift statuses for every mountain 
 
* @param {string} fName the file name of the mountain 
 
* @return {promise} the promise resolved when the file is written 
 
*/ 
 
function getReport(fName) { 
 
    return fetchAndStore.run(fName); 
 
}

Ici vous pouvez voir le fichier chercher et à stocker. Ce fichier prend le nom f et requiert le fichier staticData correspondant. Ce fichier contient l'URL pour récupérer la page avec. Maintenant, la requête html est faite, et il est exécuté à travers l'analyseur. Ensuite, avec le résultat JSON analysé, cela passe par quelques étapes pour le stocker. La sortie finale devrait être deux fichiers, l'un qui stocke les rapports et l'autre qui stocke le historicSnowfall, la majeure partie de la logique dans les fonctions de fs.outputJson est de traiter les fichiers manquants.

const fs = require('fs-extra'); 
 
const fetch = require('node-fetch'); 
 

 
exports.run = (function(fName) { 
 
    // Get the staticJson 
 
    let staticJson = require(`../staticData/mountains/${fName}.json`); 
 
    // console.log(staticJson.id) 
 

 
    // Output the report 
 
    return fetch(staticJson.urls.reportFetchUrl).then(function(res) { 
 
    return res.text(); 
 
    }).then(function(html) { 
 
    // Run the html through the parser 
 
    let parser = require(`../scrapers/${staticJson.sName}.js`); 
 
    parsed = parser.run(html); 
 
    // Output the report 
 
    return fs.outputJson(
 
     `data/reports/${staticJson.id}.json`, 
 
     parsed.report 
 
    ).then(function() { 
 
     // console.log(parsed.report.lifts[0].name); 
 
     // Once output is completed 
 
     if (parsed.snowHistory) { 
 
     // If snow history is defined 
 
     // Read the old file 
 
     return fs.readJson(
 
      `data/snowHistory/${staticJson.id}.json` 
 
     ).then(function(oldJson) { 
 
      // If the date of the old json is todays date 
 
      if (oldJson[0].date === parsed.snowHistory.date) { 
 
      // Replace the first element in array 
 
      oldJson[0] = parsed.snowHistory; 
 
      return fs.outputJson(
 
       `data/snowHistory/${staticJson.id}.json`, 
 
       oldJson 
 
      ); 
 
      } else { 
 
      // If this is a fresh entry 
 
      oldJson.unshift(parsed.snowHistory); 
 
      // If the record does not exist 
 
      return fs.outputJson(
 
       `data/snowHistory/${staticJson.id}.json`, 
 
       oldJson 
 
      ); 
 
      } 
 
     }).catch(function(e) { 
 
      // If the old file cannot be read 
 
      if (e.code === 'ENOENT') { 
 
      // If the file does not exist 
 
      // Write brand new file 
 
      return fs.outputJson(
 
       `data/snowHistory/${staticJson.id}.json`, 
 
       [parsed.snowHistory] 
 
      ); 
 
      } 
 
     }); 
 
     } 
 
    }); 
 
    }); 
 
});

Pour une raison quelconque, lorsque le grattoir est en marche, environ un quart du temps, les données d'une exécution de fetchAndStore vont se confondre avec les données d'une autre exécution de fetchAndStore , ce qui signifie que les données erronées seront écrites dans le système de fichiers. Comment est-ce possible? Je pensais que puisque je fais les appels à fetchAndStore.run() séparément, les données ne pourraient pas être mélangées. Une idée de pourquoi cela se passe?

Répondre

0

La première chose que je vois est que parsed est globalement portée. Cela pourrait-il être le problème? En aparté, si vous nichez si profondément, vous devriez vraiment envisager de le casser dans quelques fonctions.

+0

Merci, je ne peux pas croire que je n'ai pas remarqué ce problème plus tôt. J'ai ajouté laisser avant la variable analysée. Cependant, cela n'a pas réglé le problème. – Pegladon