如何在等待 1 秒后发送不和谐消息

How to send discord messages after waiting 1 second

if (msg.content.toLowerCase() === "!start") {
    var gov = setInterval(go, 1000);
    var onev = setInterval(one, 1000);
    var twov = setInterval(two, 1000);
    function two(msg) {
        msg.channel.send("https://i.imgur.com/JZOCg5l.png ");
    }
    function one(msg) {
        msg.channel.send("https://i.imgur.com/gTK3Vhn.png ");
    }
    function go(msg) {
        msg.channel.send("https://i.imgur.com/3iVfYIR.png ");
    }
    function two(msg) { }
    function one(msg) { }
    function go(msg) { }
    msg.channel.sendFile("https://i.imgur.com/kOoyoZQ.png ").then(onev).then(twov).then(gov);
}

这是一个非常烦人的任务。我需要发送这些图像大约一秒钟的时间。
当前框架不断给我以下错误:

C:\Users\maver\Documents\TestBot\testlev.js:197                                                                                  
msg.channel.sendFile("https://i.imgur.com/3iVfYIR.png ");                                                                
    ^                                                                                                                                                                                                                         
TypeError: Cannot read property 'channel' of undefined at Timeout.three [as _onTimeout] 
(C:\Users\maver\Documents\TestBot\testlev.js:197:17)                                
at ontimeout (timers.js:478:11)                                                                                      
at tryOnTimeout (timers.js:302:5)                                                                                    
at Timer.listOnTimeout (timers.js:262:5)   

我已经尝试了多种不同的方法,现在正准备认输。

你的语法有点不对劲。当您执行 function two(msg){... 时,您实际上是在告诉函数您将向它传递一个新变量,并且您希望该变量名为 msg。因此, msg (在您的函数上下文中)未定义。当您从 setInterval().

调用函数时,您必须传入 msg

有两种方法可以将 msg 绑定到您的函数。我个人喜欢的方式是这样的:

//...
var gov = setInterval(go.bind(null, msg), 1000);
var onev = setInterval(one.bind(null, msg), 1000);
var twov = setInterval(two.bind(null, msg), 1000);
//...

.bind() 函数对参数赋值。被调用函数的第一个参数是 bind() 的第二个参数。 bind() 的第一个参数应该用作函数内部 this 的值。

另一种方法是使用匿名函数

//...
var gov = setInterval(function(){go(msg)}, 1000);
var onev = setInterval(function(){one(msg)}, 1000);
var twov = setInterval(function(){two(msg)}, 1000);
//...

另请注意,setInterval() 每隔一段时间重复一次函数调用。您可能正在寻找 setTimeout(),它只会在延迟后触发一次函数。

当你使用setInterval时,你应该知道它会调用该函数,但不会向它提供任何参数(甚至this)。修复它的一种方法是使用 bind:

setInterval(go.bind(null, msg), 1000)

这可行,因为 bind() 将创建一个参数为 "magically set in advance".

的新函数

这种情况下的另一种选择是不在三个函数中重新声明 msg - 在这种情况下,javascript 将尝试从存在的外部作用域中查找 msg :

function two() {
    msg.channel.send("https://i.imgur.com/JZOCg5l.png ");
}

第三,你不应该使用setInterval,而是setTimeout,它只会调用一次函数。

你遇到的第四个问题是时间问题。首先,所有三个 setTimeout 调用同时发生,因此所有三个函数将在一秒内(1000 毫秒后)被调用。一个简单的解决方法就是:

setTimeout(go, 1000);
setTimeout(one, 2000);
setTimeout(two, 3000);

但是,这将完全忽略发送每条消息所需的时间(这可能是您想要的,也可能不是您想要的)。如果您想在上一条消息发送后等待一秒钟,那么您必须执行以下操作:

msg.channel.sendFile("https://i.imgur.com/kOoyoZQ.png ").then(function() {
    setTimeout(go, 1000);
});

function go() {
    msg.channel.send("https://i.imgur.com/3iVfYIR.png").then(function() {
        setTimeout(one, 1000);
    });
}

// etc

那会很乏味,因为所有功能看起来都非常相似。所以更好的方法是创建一个消息列表,然后用一个函数发送所有消息:

var msgs = [
    "https://i.imgur.com/kOoyoZQ.png",
    "https://i.imgur.com/JZOCg5l.png",
    "https://i.imgur.com/gTK3Vhn.png",
    "https://i.imgur.com/3iVfYIR.png" 
];

function sendMsgs(msgs, delay) {
    if (msgs.length < 1) return; // we're done
    var remain = msgs.slice(1);
    var sendRemain = sendMsgs.bind(null, remain, delay);
    msg.channel.send(msgs[0]).then(function() {
        setTimeout(sendRemain, delay);
    });
}

sendMsgs(msgs, 1000);

您的代码会立即执行,因为您必须维护您正在使用的价值和承诺未被正确使用。 您可以按如下方式进行:

if (msg.content.toLowerCase() === "!start") {
    var urls = ["https://i.imgur.com/kOoyoZQ.png",
    "https://i.imgur.com/JZOCg5l.png",
    "https://i.imgur.com/gTK3Vhn.png",
    "https://i.imgur.com/3iVfYIR.png" ];
    function gov(urls){
    for(let k=0; k<urls.length;k++){
           setTimeout(function() { msg.channel.send(k); },k*1000)
    }
    }
    gov(urls);
    }