discord.js从fs.readdir中获取数组

时间:2019-12-03 19:53:07

标签: discord.js

我可以在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);
}

1 个答案:

答案 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!
}