#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 в комментарий. Это вики сообщества, поэтому я не получаю никакой репутации