问题来了。
我有一个名为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/