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?
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