我的问题是代码似乎没有按顺序运行,如下所示。
此代码适用于我正在创建的discord.js机器人。
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");
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;
如代码所示,我有一个机器人可以处理的命令对象,我有一个函数在收到消息时运行所述命令。 在整个代码中,您可以看到我已经放置了三个带有1,2和3的console.log,显示了我希望代码部分运行的顺序。运行代码并找到查询时,输出为:
I am ready!
string +
2
3
1
这表明代码的运行顺序与我预期的顺序不同。
非常感谢所有帮助:)
*更新!非常感谢你们理解为什么它不起作用。我找到了一个解决方案,在 vidid = youtubetest.respond(query, msg)
的主文件中,当变量为在函数完成之前没有分配,因此它会在没有变量的情况下进入我的其余代码。要解决此问题,我只需将 if
语句检查变量是否未定义并等待它已定义。*
答案 0 :(得分:3)
就像之前提到的那样,javascript中的很多东西都在异步中运行,因此回调处理程序。它在异步中运行的原因是为了避免远程调用“阻止”其余代码。为了避免最终陷入回调地狱,我们大多数Javascript开发人员越来越多地转向Promises。所以你的代码可能看起来更像这样:
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);
})
};
这自然需要对使用此过程的任何内容进行更改,但创建自己的原型似乎很奇怪。
此承诺返回vidid,因此您需要设置vidid = youtubetest.response(query, msg);
,并且每当调用该函数时,您都会执行以下操作:
vidid.then(function(id) {
// id is now the vidid.
});
Javascript按设计运行异步,并试图破解你的方式,让你快速到达黑暗的地方。据我所知,你也在瞄准nodeJS,这意味着一旦你开始同步运行某些东西,你就会杀掉其他用户的性能,因为每个人都必须等待同步调用才能完成。
有人建议阅读:
我还建议查找ES6语法,因为它会缩短你的代码并使生活更轻松(原生承诺只在ES6中引入,NodeJS 4及以上版本支持(或多或少))
答案 1 :(得分:0)
在javascript中,请记住,您传递给其他函数的任何回调函数都是异步调用的。即对回调函数的调用可能不会发生"按顺序"。 "按顺序"在这种情况下表示它们出现在源文件中的顺序。
只在某个事件上调用回调函数: