Tengo una aplicación en la que llamo a una API para obtener titulares y digerir ese JSON y enviar los datos al cliente a través de sockets. Modularicé todo mi código y usé diferentes archivos para mantenerme organizado. Tengo mi archivo index.js , donde simplemente llamo a las funciones para obtener datos de la API y newsDataFetcher.js es donde hago la solicitud a la API para los datos usando el módulo de solicitud. Mi problema es que, dado que la solicitud que estoy realizando es asíncrona, los datos no se pasan al archivo del servidor principal y, por lo tanto, el socket no envía ningún dato. Después de que finaliza la solicitud a la API, coloco los datos en una matriz y esa matriz está en module.exports de mi archivo newsDataFetcher.js , junto con la función que realiza la solicitud real. Entonces, dado que la matriz está en module.exports , se pasa una matriz vacía cuando necesito el archivo newsDataFetcher.js en el archivo index.js . Entonces, eso me lleva a la pregunta: ¿hay alguna forma de llamar a module.exports "a pedido" para que no pase una matriz vacía y solo pase la matriz cuando los datos terminen de descargarse de la API?
index.js :
var newsDataFetcher = require('./newsDataFetcher'); var app = express(); var server = require('http').createServer(app); var io = require('socket.io')(server); var news = []; //array for news headlines and abstracts app.set('view engine', 'ejs'); app.use(express.static(__dirname + '/views/routes/')); server.listen(8888); console.log("Running server on http://localhost:8888 ...."); newsDataFetcher.getNewsData(); news = newsDataFetcher.news; setInterval(function () { newsDataFetcher.getNewsData(); news = newsDataFetcher.news; }, 6000000); setInterval(function () { sendAllData() }, 1000); function sendAllData() { io.sockets.emit('news', news); } archivo newsDataFetcher.js :
var request = require('request'); var nyTimesApi = "http://api.nytimes.com/svc/topstories/v1/home.json?api-key=" + nyTimesApiKey_DEV; var news = []; //array for news headlines and abstracts function getNewsData() { request({ url: nyTimesApi, json: true }, function (err, res, body) { news = body.results; }); } module.exports = { getNewsData: getNewsData, news: news }Puedes hacer algo como esto:
// newsDataFetcher.js module.exports = { getNewsData: getNewsData, news: function() { return news; } } // index.js io.sockets.emit('news', newsDataFetcher.news());Puede usar el patrón singleton para lograr esto.
class NewsDataFetcher { constructor() { this.news = []; } getNewsData() { const self = this; request({ url: nyTimesApi, json: true }, function (err, res, body) { self.news = body.results; }); } } module.exports = new NewsDataFetcher();En la página principal.
var newsDataFetcher = require('./newsDataFetcher'); newsDataFetcher.getNewsData(); // to fetch new data; // To get news data console.log(newsDataFetcher.news); // will always refer to one instance of news since you are using singleton.