这段代码似乎没有按顺序开火?

我的问题是,代码似乎没有按顺序运行,如下所示。

这个代码是我创build的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; 

如代码所示,我有一个可以处理的命令的对象,并且我有一个函数来在收到消息时运行这些命令。 在整个代码中,你可以看到,我已经把三个console.logs与1,2和3显示我期望的代码部分运行的顺序。 当代码运行并且发现查询时,输出是这样的:

 I am ready! string + 2 3 1 

这表明代码按照我预期的错误顺序运行。

所有的帮助是非常高度赞赏:)

*更新! 非常感谢大家,了解它为什么不起作用。 我发现了一个解决scheme,在 vidid = youtubetest.respond(query, msg) 的主文件中 vidid = youtubetest.respond(query, msg) 当variables没有被分配时,直到函数完成,所以它没有variables就进入我的代码的其余部分。 为了解决这个问题,我只是简单地放一个 if 语句来检查variables是否未定义,并等待它被定义。

就像之前提到的,很多javascript中的东西在async中运行,因此是callback处理程序。 它以asynchronous方式运行的原因是为了避免其他代码被远程调用“阻塞”。 为了避免在callback地狱结束,我们大多数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); }) }; 

这自然需要改变任何使用这个过程的东西,但是创build你自己的原型似乎很奇怪。

这个promise会返回vidid,所以你可以设置vidid = youtubetest.response(query, msg); ,而且每当这个函数被调用时,你都会这样做:

 vidid.then(function(id) { // id is now the vidid. }); 

JavaScript通过devise运行asynchronous,并试图绕开你的方式导致你快速到黑暗的地方。 据我所知,你也瞄准nodeJS,这意味着,一旦你开始同步运行的东西,你会杀了其他用户的性能,因为每个人都必须等待同步呼叫完成。

一些build议阅读:

我也build议查找ES6的语法,因为它缩短了你的代码,使生活变得更加容易(原生承诺只在ES6中引入,NodeJS 4及以上版本支持(或多或less))

在JavaScript中,请记住,传递给其他函数的任何callback函数都是asynchronous调用的。 即callback函数的调用可能不会“按顺序”发生。 在这种情况下,“按顺序”是指它们在源文件上出现的顺序。

callback函数只是在某些事件上调用:

  • 有数据要处理时
  • 错误
  • 在您的情况下,例如,当YouTube的search结果准备好了,“就绪”事件被接收或“消息”被收到。
  • 等等