javascript - 从回调函数内部将项目添加到全局数组,然后全局访问它

标签 javascript node.js callback

问题来了。

我有一个名为folders的全局变量(数组类型)

let folders = [];

我在另一个回调函数中的回调函数中修改它。 方法如下。

app.get("/", (req, res) => {
// TODO: Proceed only if the path is correct and it is a directory
fs.readdir(dir, (err, files) => {
    console.log("READING:");

    if (err) throw err;

    files.forEach(file => {
        const add = folder => folders.push(folder);
        fs.lstat(path.join(dir, file), (err, stats) => {
            if (err) throw err;

            if (stats.isDirectory()) {
                add(file);
            }
            console.log("INSIDE: " + folders);
        });
        console.log("OUTSITE: " + folders);
    });
});

res.send(folders.length.toString());
});

现在的问题是,当我在这一行阅读它时:

res.send(folders.length.toString());

长度始终为 0。 在我用 OUTSITE 打印它的控制台日志行上它也是 0 但是当我在用 内部

经过一番搜索,我知道了这个问题。发生这种情况是因为回调在事件循环的稍后时间设置了变量。(如果它有任何意义,但你明白了)。

我知道这个问题,但我不知道如何解决它。我已经尝试了各种实现,包括添加一个推送到数组的全局函数,并在回调中调用它 frpm,但结果是一样的。

这是完整的代码。

const express = require("express");
const fs = require("fs");
const path = require("path");
const os = require("os");

// Initialize Express
const app = express();

// PORT on which the app process should be started
const PORT = process.env.PORT || 5100;

// Setting Up the path to Projects folder dynamically
// !Currently only works(tested) on the Darwin(MacOS) systems PS. I don't own a Windows
// TODO: Test on Windowsn and Linux
const homedir = os.homedir();
const dir = `${homedir}/Projects/`;

// TODO: Re-Write using Async/Await as it is not fully suppported as of Node version 10.0

let folders = [];

// Home Route
app.get("/", (req, res) => {
    // TODO: Proceed only if the path is correct and it is a directory
    fs.readdir(dir, (err, files) => {
        console.log("READING:");

        if (err) throw err;

        files.forEach(file => {
            const add = folder => folders.push(folder);
            fs.lstat(path.join(dir, file), (err, stats) => {
                if (err) throw err;

                if (stats.isDirectory()) {
                    add(file);
                }
                console.log("INSIDE: " + folders);
            });
            console.log("OUTSITE: " + folders);
        });
    });

    res.send(folders.length.toString());
});

// Start the express server
app.listen(PORT, err => {
    if (err) throw err;
    console.log(`Project Lister Running On PORT: ${PORT}`);
});

有什么解决办法吗?

最佳答案

这里的问题是 fs.lstat 是异步的。

如果您使用同步版本fs.lstatSync,那么您可以在forEach 循环之后调用res.send

app.get("/", (req, res) => {
  // TODO: Proceed only if the path is correct and it is a directory
  fs.readdir(dir, (err, files) => {
      console.log("READING:");

      if (err) throw err;

      files.forEach(file => {
          const add = folder => folders.push(folder);
          try {
            const stats = fs.lstatSync(path.join(dir, file))

            if (stats.isDirectory()) {
              add(file);
          }
          } catch (err) {
            throw err
          }
      });

      res.send(folders.length.toString());
  })
})

或者对于非阻塞方式,您可以使用 Promise.all:

app.get("/", (req, res) => {
  // TODO: Proceed only if the path is correct and it is a directory
  fs.readdir(dir, (err, files) => {
    console.log("READING:");

    if (err) throw err;

    const promises = files.map(file => {
      return new Promise((resolve, reject) => {
        fs.lstat(path.join(dir, file), (err, stats) => {
          if (err) {
            reject(err);
          }
          if (stats.isDirectory()) {
            add(file);
            resolve();
          }
          console.log("INSIDE: " + folders);
        });
      });
    });

    Promise.all(promises, () => {
      res.send(folders.length.toString());
    });
  });
});

关于javascript - 从回调函数内部将项目添加到全局数组,然后全局访问它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58144561/

相关文章:

node.js - Node/Express - 保护客户端/服务器之间通信的好方法

javascript - 使用 JQuery 切换功能显示/隐藏 youtube 但无法让它在隐藏时停止播放

javascript - 如何将 .draggable 限制为缩放的 div?

javascript - hasAttribute 函数是否允许属性的 ID 或名称?

javascript - String Split 只是第一次

javascript - 在 Meteor 中添加公共(public) JS

node.js - 存储静态内容时应用程序大小重要吗?

c++ - 指定内联回调函数作为参数

c++ - 在 C++ 中是否有任何事件/委托(delegate)/接口(interface)/通知!任何事物?

javascript - 将数据从回调传递到 React 组件?