My problem is that the code does not seem to be running in order, as seen below.
我的问题是代码似乎没有按顺序运行,如下所示。
This code is for my discord.js bot that I am creating.
这是我的不和谐代码。我正在创建的js bot。
var Discord = require("discord.js");
var bot = new Discord.Client();
var yt = require("C:/Users/username/Documents/Coding/Discord/youtubetest.js");
var youtubetest = new yt();
var fs = require('fs');
var youtubedl = require('youtube-dl');
var prefix = "!";
var vidid;
var commands = {
play: {
name: "!play ",
fnc: "Gets a Youtube video matching given tags.",
process: function(msg, query) {
youtubetest.respond(query, msg);
var vidid = youtubetest.vidid;
console.log(typeof(vidid) + " + " + vidid);
console.log("3");
}
}
};
bot.on('ready', () => {
console.log('I am ready!');
});
bot.on("message", msg => {
if(!msg.content.startsWith(prefix) || msg.author.bot || (msg.author.id === bot.user.id)) return;
var cmdraw = msg.content.split(" ")[0].substring(1).toLowerCase();
var query = msg.content.split("!")[1];
var cmd = commands[cmdraw];
if (cmd) {
var res = cmd.process(msg, query, bot);
if (res) {
msg.channel.sendMessage(res);
}
} else {
let msgs = [];
msgs.push(msg.content + " is not a valid command.");
msgs.push(" ");
msgs.push("Available commands:");
msgs.push(" ");
msg.channel.sendMessage(msgs);
msg.channel.sendMessage(commands.help.process(msg));
}
});
bot.on('error', e => { console.error(e); });
bot.login("mytoken");
The youtubetest.js file:
youtubetest。js文件:
var youtube_node = require('youtube-node');
var ConfigFile = require("C:/Users/username/Documents/Coding/Discord/json_config.json");
var mybot = require("C:/Users/username/Documents/Coding/Discord/mybot.js");
function myyt () {
this.youtube = new youtube_node();
this.youtube.setKey(ConfigFile.youtube_api_key);
this.vidid = "";
}
myyt.prototype.respond = function(query, msg) {
this.youtube.search(query, 1, function(error, result) {
if (error) {
msg.channel.sendMessage("There was an error finding requested video.");
} else {
vidid = 'http://www.youtube.com/watch?v=' + result.items[0].id.videoId;
myyt.vidid = vidid;
console.log("1");
}
});
console.log("2");
};
module.exports = myyt;
As the code shows, i have an object for the commands that the bot will be able to process, and I have a function to run said commands when a message is received. Throughout the code you can see that I have put three console.logs with 1, 2 and 3 showing in which order I expect the parts of the code to run. When the code is run and a query is found the output is this:
正如代码所示,我有一个对象用于机器人能够处理的命令,我有一个函数在收到消息时运行所述命令。在整个代码中,您可以看到我放置了三个控制台。日志中显示的1、2和3的顺序是我期望代码的各个部分运行的顺序。当代码运行并找到查询时,输出如下:
I am ready!
string +
2
3
1
This shows that the code is running in the wrong order that I expect it to.
这表明代码运行的顺序是错误的。
All help is very highly appreciated :)
非常感谢您的帮助。
*Update! Thank you all very much to understand why it isn't working. I found a solution where in the main file at vidid = youtubetest.respond(query, msg)
when it does that the variable is not assigned until the function is done so it goes onto the rest of my code without the variable. To fix I simply put an if
statement checking if the variable if undefined and waiting until it is defined.*
*更新!非常感谢大家理解它为什么不起作用。我在vidid = youtubetest的主文件中找到了一个解决方案。response (query, msg)当它这么做时,直到函数完成后才会分配变量,所以它会进入代码的其余部分,而不是变量。为了修复,我只是简单地设置一个if语句,检查变量是否未定义,并等待它被定义。
2 个解决方案
#1
2
Like is mentioned before, a lot of stuff in javascript runs in async, hence the callback handlers. The reason it runs in async, is to avoid the rest of your code being "blocked" by remote calls. To avoid ending up in callback hell, most of us Javascript developers are moving more and more over to Promises. So your code could then look more like this:
正如前面提到的,javascript中的很多东西都在异步中运行,因此出现了回调处理程序。它在异步中运行的原因是为了避免远程调用“阻塞”代码的其余部分。为了避免陷入回调地狱,我们大多数Javascript开发人员越来越倾向于承诺。所以你的代码可以看起来更像这样:
myyt.prototype.respond = function(query, msg) {
return new Promise(function(resolve, reject) {
this.youtube.search(query, 1, function(error, result) {
if (error) {
reject("There was an error finding requested video."); // passed down to the ".catch" statement below
} else {
vidid = 'http://www.youtube.com/watch?v=' + result.items[0].id.videoId;
myyt.vidid = vidid;
console.log("1");
resolve(2); // Resolve marks the promises as successfully completed, and passes along to the ".then" method
}
});
}).then(function(two) {
// video is now the same as myyt.vidid as above.
console.log(two);
}).catch(function(err) {
// err contains the error object from above
msg.channel.sendMessage(err);
})
};
This would naturally require a change in anything that uses this process, but creating your own prototypes seems.. odd.
这自然需要对使用此过程的任何东西进行更改,但创建自己的原型似乎是……奇数。
This promise returns the vidid, so you'd then set vidid = youtubetest.response(query, msg);
, and whenever that function gets called, you do:
这个承诺会返回vidid,因此您将设置vidid = youtubetest。响应(query, msg);,无论何时调用该函数,您都会:
vidid.then(function(id) {
// id is now the vidid.
});
Javascript runs async by design, and trying to hack your way around that leads you to dark places fast. As far as I can tell, you're also targetting nodeJS, which means that once you start running something synchronously, you'll kill off performance for other users, as everyone has to wait for that sync call to finish.
Javascript是通过设计来运行异步的,并且试图改变你的方式,这会使你快速地到达黑暗的地方。据我所知,您还在target nodeJS,这意味着一旦您开始同步运行一些东西,您将会破坏其他用户的性能,因为每个人都必须等待同步调用结束。
Some suggested reading:
一些建议阅读:
- http://callbackhell.com/
- http://callbackhell.com/
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
- https://*.com/a/11233849/3646975
- https://*.com/a/11233849/3646975
I'd also suggest looking up ES6 syntax, as it shortens your code and makes life a hellofalot easier (native promises were only introduced in ES6, which NodeJS 4 and above supports (more or less))
我还建议使用ES6语法,因为它缩短了您的代码,使hellofalot变得更简单(本地的承诺只在ES6中引入,NodeJS 4及以上支持(或多或少))
#2
0
In javascript, please remember that any callback function you pass to some other function is called asynchronously. I.e. the calls to callback function may not happen "in order". "In order" in this case means the order they appear on the source file.
在javascript中,请记住传递给其他函数的任何回调函数都是异步调用的。也就是说,回调函数的调用可能不会“按顺序”发生。“In order”在本例中表示它们出现在源文件中的顺序。
The callback function is simply called on certain event:
回调函数只在某些事件上调用:
- When there is data to be processed
- 当有数据需要处理时
- on error
- 在错误
- in your case for example when the youtube search results are ready, 'ready' event is received or 'message' is received.
- 例如,当youtube搜索结果就绪时,会接收到“ready”事件或“message”。
- etc.
- 等。
#1
2
Like is mentioned before, a lot of stuff in javascript runs in async, hence the callback handlers. The reason it runs in async, is to avoid the rest of your code being "blocked" by remote calls. To avoid ending up in callback hell, most of us Javascript developers are moving more and more over to Promises. So your code could then look more like this:
正如前面提到的,javascript中的很多东西都在异步中运行,因此出现了回调处理程序。它在异步中运行的原因是为了避免远程调用“阻塞”代码的其余部分。为了避免陷入回调地狱,我们大多数Javascript开发人员越来越倾向于承诺。所以你的代码可以看起来更像这样:
myyt.prototype.respond = function(query, msg) {
return new Promise(function(resolve, reject) {
this.youtube.search(query, 1, function(error, result) {
if (error) {
reject("There was an error finding requested video."); // passed down to the ".catch" statement below
} else {
vidid = 'http://www.youtube.com/watch?v=' + result.items[0].id.videoId;
myyt.vidid = vidid;
console.log("1");
resolve(2); // Resolve marks the promises as successfully completed, and passes along to the ".then" method
}
});
}).then(function(two) {
// video is now the same as myyt.vidid as above.
console.log(two);
}).catch(function(err) {
// err contains the error object from above
msg.channel.sendMessage(err);
})
};
This would naturally require a change in anything that uses this process, but creating your own prototypes seems.. odd.
这自然需要对使用此过程的任何东西进行更改,但创建自己的原型似乎是……奇数。
This promise returns the vidid, so you'd then set vidid = youtubetest.response(query, msg);
, and whenever that function gets called, you do:
这个承诺会返回vidid,因此您将设置vidid = youtubetest。响应(query, msg);,无论何时调用该函数,您都会:
vidid.then(function(id) {
// id is now the vidid.
});
Javascript runs async by design, and trying to hack your way around that leads you to dark places fast. As far as I can tell, you're also targetting nodeJS, which means that once you start running something synchronously, you'll kill off performance for other users, as everyone has to wait for that sync call to finish.
Javascript是通过设计来运行异步的,并且试图改变你的方式,这会使你快速地到达黑暗的地方。据我所知,您还在target nodeJS,这意味着一旦您开始同步运行一些东西,您将会破坏其他用户的性能,因为每个人都必须等待同步调用结束。
Some suggested reading:
一些建议阅读:
- http://callbackhell.com/
- http://callbackhell.com/
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
- https://*.com/a/11233849/3646975
- https://*.com/a/11233849/3646975
I'd also suggest looking up ES6 syntax, as it shortens your code and makes life a hellofalot easier (native promises were only introduced in ES6, which NodeJS 4 and above supports (more or less))
我还建议使用ES6语法,因为它缩短了您的代码,使hellofalot变得更简单(本地的承诺只在ES6中引入,NodeJS 4及以上支持(或多或少))
#2
0
In javascript, please remember that any callback function you pass to some other function is called asynchronously. I.e. the calls to callback function may not happen "in order". "In order" in this case means the order they appear on the source file.
在javascript中,请记住传递给其他函数的任何回调函数都是异步调用的。也就是说,回调函数的调用可能不会“按顺序”发生。“In order”在本例中表示它们出现在源文件中的顺序。
The callback function is simply called on certain event:
回调函数只在某些事件上调用:
- When there is data to be processed
- 当有数据需要处理时
- on error
- 在错误
- in your case for example when the youtube search results are ready, 'ready' event is received or 'message' is received.
- 例如,当youtube搜索结果就绪时,会接收到“ready”事件或“message”。
- etc.
- 等。