我可以在emotes
中读取fs.readdir
,但是不能从fs.readdir
函数中读取它们。有什么办法可以在其他地方阅读它们?
const Discord = require("discord.js");
module.exports.run = async (client, message, args) => {
const fs = require("fs");
var emotes = [];
fs.readdir("./images/gif", (err, files) => {
if(err) console.log(err);
let giffile = files;
if(giffile.length <= 0) {
return console.log("Couldn't find any gif files");
}
giffile.forEach((f, i) => {
emotes.push(f.split(".")[0]);
});
console.log(emotes);
});
console.log(emotes);
}
答案 0 :(得分:2)
这并不是说您无法在回调函数之外读取emotes
,而是您错过了回调的要点。
此:
fs.readdir("./images/gif", (err, files) => {
...
});
之所以这样写是由于一个非常特定的原因:您正在调用函数fs.readdir(path,callback)
,为回调提供函数(err, files) => { ... }
。为什么fs.readdir()
不像任何普通函数那样只返回结果,而不是让您赋予它另一个函数?这是因为它是异步-实际上,您赋予的功能已安排预定,以便将来在操作系统完成从磁盘读取操作后运行一些不确定的时间-您不知道何时可能会,但是您可以告诉它在那个时候该怎么办。
您的外部run
函数不会在这个不确定的时间内等待,如果这样做,您的机器人将冻结直到完成读取,这是一个坏消息。相反,它计划稍后再调用该回调,然后继续进行到下一行-console.log(emotes);
。请记住,回调尚未运行,因此emotes
自然没有得到任何值。
如果您需要编写异步代码(例如同步代码),则密钥为Promises和async / await。我看到您已经将run
函数标记为异步,因此您可以轻松地将readdir
调用包装在Promise中,如下所示:
module.exports.run = async (client, message, args) => {
const fs = require("fs");
var emotes = [];
await new Promise((resolve,reject) => { fs.readdir("./images/gif", (err, files) => {
if(err) reject(err);
let giffile = files;
if(giffile.length <= 0) {
return console.log("Couldn't find any gif files");
}
giffile.forEach((f, i) => {
emotes.push(f.split(".")[0]);
});
resolve();
});
console.log(emotes); //works!
}
或者,您可以在节点v10或更高版本上使用fs.Promises
API跳过整个回调:
module.exports.run = async (client, message, args) => {
const fs = require("fs").promises;
var emotes = [];
var files = await fs.readdir("./images/gif");
let giffile = files;
if(giffile.length <= 0) {
return console.log("Couldn't find any gif files");
}
giffile.forEach((f, i) => {
emotes.push(f.split(".")[0]);
});
console.log(emotes); //works!
}
或更短更有效:
const fs = require("fs").promises;
module.exports.run = async (client, message, args) => {
var emotes = (await fs.readdir("./images/gif")).map(f => f.split(".")[0]);
if(emotes.length <= 0) {
return console.log("Couldn't find any gif files");
}
console.log(emotes); //works!
}