startTypingの簡易版を実装してみる
code:js
const Discord = require("discord.js");
const client = new Discord.Client({
});
const map = new Map();
function get_or_set(map, k, default_v) {
if (map.has(k)) {
return map.get(k);
}
map.set(k, default_v);
return default_v;
}
function create_aborted_event_handler(client_map, context) {
const handler = () => {
--context.count;
if (context.count !== 0) {
return;
}
const v = client_map.get(context.channel_id);
if (v === context) {
clearInterval(context.timeout);
client_map.delete(context.channel_id);
context.resolve();
}
};
return handler;
}
/**
*
* @param {Discord.TextChannel|Discord.NewsChannel|Discord.DMChannel|Discord.ThreadChannel} channel
* @param {AbortSignal} signal
* @returns
*/
function startTyping(channel, signal) {
const client_map = get_or_set(map, channel.client, new Map());
const channel_id = channel.id;
const context = get_or_set(client_map, channel_id, {
count: 0,
channel_id,
});
++context.count;
signal.addEventListener("abort", create_aborted_event_handler(client_map, context));
if (context.count !== 1) {
return context.promise;
}
let reject;
context.promise = new Promise((...args) => {
});
const exec = async () => {
try {
await channel.sendTyping();
} catch (err) {
clearInterval(context.timeout);
client_map.delete(channel.id);
reject(err);
}
};
context.timeout = setInterval(exec, 9 * 1000);
exec();
return context.promise;
}
client.on("messageCreate", (message) => {
const controller = new AbortController();
startTyping(message.channel, controller.signal).then(() => console.log("resolved"),err => console.error(err));
setTimeout(() => controller.abort(), 20 * 1000);
});
client.login();
関連