Diskuze: Nedokážu napsat jednoduchý setTimeout příkaz do správné formy.
V předchozím kvízu, Online test znalostí JavaScript, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 12 zpráv z 12.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí JavaScript, jsme si ověřili nabyté zkušenosti z kurzu.
Nechápeš jak funguje setTimeout. To co děláš teď pošle zprávu "Jednoduchý text s názvy příkazů" a následně po 20 sekundách pošleš reply s textem "Vydrž prosím 20 sekund.".
Jak sám vidíš, to nechceš. Tvůj záměr je odeslat odpověď pouze pokud uplynula nějaká doba. To můžeš udělat například takto:
nastavit proměnou s časem poslední zprávy a pokud někdo použije příkaz, zkontroluješ zda je uložený čas + 20 sekund méně/dřív než aktuální čas; pokud ano, nastavíš do proměnné novou hodnotu a odešleš zprávu
Konceptuálně nějak takto, například: (samozřejmě je nutné si to přepsat a doladit)
const PREFIX = '!rot ';
bot.on('ready', () =>{
console.log('This bot is online!');
})
var lastMesage;
bot.on('message', message=>{
let args = message.content.slice(PREFIX.length).split(' ');
switch(args[0]){
case "komandy":
if (canSendMessage()) { // kontrola
message.channel.send('*Jednoduchý text s názvy příkazů*');
lastMesage = new Date(); // nastavení poslední zprávy
}
break;
}
}
function canSendMessage() {
var now = new Date();
if (lastMessage == null) {
lastMessage = now;
return true;
}
var lastMessageValue = lastMessage;
lastMessageValue.setSeconds(lastMessageValue .getSeconds() + 20);
return lastMessageValue <= now);
}
Možná jsem tě nepochopil správně, ale rozumím tomu tak že to napíše zprávu a po 20 sekundách to napíše zprávu "Vydrž prosím 20 sekund.". Pokud ano, funguje to správně, setTimeout slouží k tomu aby se to za určitou dobu vykonalo.
Pokud chceš udělat to aby po dobu 20 sekund nebude moct psát daný příkaz, tak to musíš jinak.
Teoreticky by to šlo udělat tak, že bys měl pole do které by sis
ukládal autora zprávy případně jeho ID a vždy když se napíše příkaz
tak by se ověřilo jestli dané ID/author v poli je a pokud není tak by se
vykonal příkaz a přidal by se do pole a za 20 sekund s využitím té funkce
setTimeout()
. Netestoval jsem to, napsal jsem to narychlo ale
můžeš to vyzkoušet.
const PREFIX = '!rot ';
bot.on('ready', () =>{
console.log('This bot is online!');
})
let spam; // pole lidí co napsali
bot.on('message', message=>{
let args = message.content.slice(PREFIX.length).split(' ');
switch(args[0]){
case "komandy":
let member_id = message.member.id || message.member.user.id;
if(!spam.includes(member_id)) { // pokud napsal v poslednich 20s
message.channel.send('*Jednoduchý text s názvy příkazů*');
spam.push(member_id);
setTimeout(() => { // za 20s se odstrani a muze psat dal
spam.splice(spam.length, spam.length);
}, 20000)
}
break;
Krom toho doporučuji na tvorbu discord bota si udělat nějaký command handler, bude to lepší než abys to takhle patlal.
A možná lepší řešení by bylo vytvořit roomku pouze na příkazy a dát tam aby se mohlo psát pouze jednou za 20s.
Skript nefunguje. Program nezná funkci "lastMessage" nebo alespoň to píše.
Staci si zkontrolovat ten kod a najdes proc, ale asi by to stejnak nefungovalo tak jak chces, vzhledem k tomu ze by to ucinkovalo i na ty co zadnou zprávu nenapsali.
setTimeout(function(){message.reply("Vydrž prosím 20 sekund."); }, 20000);
idtimer = setTimeout("bbb", 20000);
//clearTimeout(idtimer ); pro zastaveni timeru
//idtimer = setInterval("bbb", 20000); // pro opakovany timer
function bbb()
{
message.reply("Vydrž prosím 20 sekund.");
}
Jenze, message neni globalni promenna, nebude automaticky viditelna v cizi
funkci a timer zadne promenne nepredava. Takze by bylo vyhodnejsi si udelat
tridu (class).
Takhle nejak by to mohlo fungovat, ale nevim, jak se to zapisuje v
let-javascriptu, jen v klasickem. Let syntaxe je mi vicemene ukradena
var obj = {};
obj.message = null;
obj.idtimer = null;
obj.bbb = function() {this.message.reply("Vydrž prosím 20 sekund.");}
//obj.start = function() {this.idtimer = setTimeout(this.bbb, 20000);}
obj.start = function() {this.idtimer = setTimeout("this.bbb", 20000);}
obj.message = message;
obj.start();
Jeste mozna jiny priklad, vsude muze byt to obj, ale nekde funguje i this. Aby fungovalo this vsude, tak by se to muselo napsat jinak. Ale tohle ti asi staci.
// https://jsfiddle.net/qax4w2ht/
var obj = {};
obj.x = 0;
obj.message = null;
obj.idtimer = null;
obj.bbb = function() {obj.message.reply("Vydrž prosím 20 sekund." + obj.x);}
obj.start = function() {this.x=1; this.idtimer = setTimeout(this.bbb, 1000);}
obj.message = {};
obj.message.reply = function(str) {window.alert(str);};
obj.start();
Jde o to, ze ve funkci, kterou volas v timeru (bbb), nemas zadne vazby, proto tam musi byt 'obj' a ne 'this'.
Ale, mozna jsi mel chybu nekde jinde, protoze je mozna i varianta.
setTimeout(function() {
postinsql(topicId);
}, 4000)
---
var that = this; setTimeout( function() { that.foo(); }, 1000);
https://stackoverflow.com/…out-callback
...nalezeno googlem
Očividně můj skript nefunguje, taky jsem psal, že je to koncept + samozřejmě musíš upravit kód dle svých požadavků.
To co posílal Milan Turyna vypadá fajn, pokud je tvůj požadavek omezit každého uživatele zvlášť.
Já jsem to včera zkoušel ale funguje to pouze "na půl" protože se neodstraňuje z pole a taktéž sem zapomněl nastavit že to je pole. Spíš by bylo lepší místo setTimeout použít ověřování podle času, discord to asi nějak blokuje nevím.
Jo tak ale koncepčně to je ok. Já jsem názoru že je lepší kontrolovat ten čas, než timeoutouvat, protože to je méně error prone. Ale oboje by mělo IMO fungovat.
Zobrazeno 12 zpráv z 12.