Как сделать node.js webscraper периодически проверяет конечную точку на наличие обновлений данных?

#javascript #node.js #events #web-scraping #emit

#javascript #node.js #Мероприятия #очистка веб-страниц #испускать

Вопрос:

Я пишу discord-бота, который собирает данные из стороннего API.

Существует шаблон проектирования discord.js , которому я хочу следовать для своих функций очистки веб-страниц, в котором создается экземпляр объекта клиента и выполняются действия, когда клиент отправляет определенные события, например:

 const Discord = require('discord.js');
const client = new Discord.Client();

client.on('ready', () => {
  console.log(`Logged in as ${client.user.tag}!`);
});

client.on('message', msg => {
  if (msg.content === 'ping') {
    msg.reply('Pong!');
  }
});

client.login('token');
  

Насколько я понимаю, этот код будет выполняться бесконечно, выполняя действия каждый раз при отправке определенного события, например ready , или message .

Я не могу узнать, как реализована такая функциональность. Более конкретно, я не могу понять, как объект discord client постоянно ищет изменения и выдает событие, когда он их замечает.

Причина, по которой я хочу эмулировать этот шаблон проектирования, заключается в том, что я могу его запустить node.js приложение, которое будет, скажем, каждые 10 минут обращаться к API и проверять, есть ли новая информация, и регистрировать ее в базе данных при появлении изменений.

Моя первоначальная мысль — что-то в этом роде, но она приводит к сбою в стеке вызовов из-за ошибки нехватки памяти.

 const events = require("events");

class ScrapeEmitter extends events.EventEmitter {}
const scrapeEmitter = new ScrapeEmitter();

scrapeEmitter.on("timeExpired", () => console.log("call scraping code here"));

while (true) {
  setTimeout(() => scrapeEmitter.emit("timeExpired"), 1500);
}
  

Конечная цель состоит в том, чтобы, начиная с index.js , написать следующее и заставить его одновременно прослушивать события discord, а также собирать данные.

 import * as scraper from "./core/scraper";
const Discord = require('discord.js');
const client = new Discord.Client();

client.on('ready', () => {
  console.log(`Logged in as ${client.user.tag}!`);
});

client.on('message', msg => {
  if (msg.content === 'ping') {
    msg.reply('Pong!');
  }
});

client.login('token');
scraper.begin_scraping();
  

Комментарии:

1. вероятно, вы можете использовать setInterval вместо setTimeout и выйти из while цикла.

2. Я думаю, что именно так это и должно работать, спасибо!

Ответ №1:

Эта часть кода

 while (true) {
  setTimeout(() => scrapeEmitter.emit("timeExpired"), 1500);
}
  

создает бесконечное количество таймаутов. Что вам нужно сделать, это начать тайм-аут только после завершения предыдущего. Примером является:

 function loop() {
setTimeout(loop, 1500);
}
  

Это вызывает функцию через 1500 секунд, которая, в свою очередь, вызывает функцию через 1500 секунд и так далее.

Однако лучшим решением является использование setInterval() . Это выглядит так:

 function loop() {};
setInterval(loop, 1500);
  

Итак, вместо того, чтобы писать

 while (true) {
  setTimeout(() => scrapeEmitter.emit("timeExpired"), 1500);
}
  

Написать

 setInterval(() => scrapeEmitter.emit("timeExpired"), 1500);
  

Это удаляет бесконечный цикл и действует, как ожидалось.

Я просто перевожу ответ @Worthy Alpaca в комментарий. Это вики сообщества, поэтому я не получаю никакой репутации