Javascript 此代码没有';似乎没有按顺序开火?
我的问题是代码似乎没有按顺序运行,如下所示 这段代码是为我正在创建的discord.js bot编写的Javascript 此代码没有';似乎没有按顺序开火?,javascript,node.js,scope,youtube-data-api,discord,Javascript,Node.js,Scope,Youtube Data Api,Discord,我的问题是代码似乎没有按顺序运行,如下所示 这段代码是为我正在创建的discord.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 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;
正如代码所示,我有一个用于bot能够处理的命令的对象,并且我有一个函数在收到消息时运行所述命令。
在整个代码中,您可以看到我放置了三个console.log,其中1、2和3显示了我希望代码部分按什么顺序运行。运行代码并找到查询时,输出如下:
I am ready!
string +
2
3
1
这表明代码以我期望的错误顺序运行
非常感谢所有帮助:)
*更新!非常感谢大家理解为什么它不起作用。我找到了一个解决方案,在主文件中的
vidid=youtubetest.respond(query,msg)
中,当它这样做时,变量在函数完成之前不会被赋值,因此它会进入代码的其余部分,而不带变量。要修复此问题,我只需放置一个if
语句,检查变量是否未定义,并等待它被定义。*在javascript中,请记住传递给其他函数的任何回调函数都是异步调用的。也就是说,对回调函数的调用可能不会“按顺序”进行。在本例中,“顺序”是指它们在源文件上出现的顺序
回调函数仅在特定事件上调用:
- 当有数据需要处理时
- 论错误
- 以您的情况为例,当youtube搜索结果就绪时, 收到“就绪”事件或收到“消息”
- 等等
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及以上版本支持(或多或少))您正在编写异步代码。console.log 2在异步函数之外。我不确定你会期望发生什么。很抱歉,我没有做过很多类似的事情,我还是个十几岁的孩子,还在学习Javascript。什么是异步,什么部分是异步和非异步?this.youtube.search
可能是一个异步函数,这意味着它在后台执行某些操作,而函数回调之外的其他代码继续执行。因此,您的函数(error,result){…}
是只在搜索操作完成后执行的回调。因此,console.log(2)
自然会在回调之前被调用。但是第一个文件中的console.log(3)
首先运行,所以函数youtubetest.respond(query,msg)
不应该在console.log(3)
之前运行吗?youtubetest.respond
可能也是异步的。啊,好的,但是如何将变量vidid
与youtube搜索结果一起返回mybot.js呢。我应该在这个问题上做得更好。那是另一个问题。:-)在播放函数中,从vidid变量的开头删除“var”,这样就不会覆盖上面几行的vidid变量。然后在代码的其他地方检查vidid!==我接受了你的建议,但这并没有改变结果。输出仍然是string+
谢谢@teroi。我更新了上面的文字,展示了我解决问题的方法。谢谢,这确实有助于解释我的问题,虽然我意识到问题是错的,但它仍然对我有很大帮助。非常感谢!:)