gpt4 book ai didi

javascript - 即使在 Node.js 中的回调函数之后,函数也会异步运行

转载 作者:行者123 更新时间:2023-12-03 02:42:26 25 4
gpt4 key购买 nike

我正在尝试使用 Node.js 的“fs”模块创建一个文件浏览器。

我编写了以下函数,它接受一个路径并将该路径的内容(文件/文件夹)存储在一个数组中,然后使用回调将其发送回来。

listDir: function (path, myCallback) {
var resultObj = [];

fs.readdir(path, function (err, data) {
console.log('In listDir');
if (err) {
return myCallback(err, null);
} else {

data.forEach(function (value) {

fs.lstat(path + '/' + value, function (err, stats) {

if (err) {
console.log(err);
} else {
//console.log('Size-' + stats.isFile()+'\n');
if(stats.isFile()){
//console.log('is file----\n');
/*resultObj.push({
type: 'file',
name: value,
size: stats['size']
});*/
resultObj.push(value);
console.log(resultObj+'\n');

} else if(stats.isDirectory()){
//console.log('is folder----\n');
/*resultObj.push({
type: 'folder',
name: value,
size: stats['size']
});*/
resultObj.push(value);
console.log(resultObj+'\n');
}
}
});

});
console.log('Resultant obj-' + resultObj);
return myCallback(null, resultObj);
}
});

}

对于存储在“data”中的每个文件/文件夹,我尝试检查它是文件还是文件夹,并根据情况将对象插入“resultObj”数组中。然而,return 语句甚至在 forEach 完成之前就被执行,因此我每次都会得到一个空的 resultObj。

为什么会发生这种情况?为什么即使我提供了回调函数它也会异步运行?

当我使用路径参数调用/test 路由时,输出是这样的--

在列表目录中
结果对象-
GET/test?path=F:\dummyFolder 304 15.210 毫秒 - -
文件1
文件1,文件2
文件1,文件2,文件夹3

请帮我解决这个问题,我真的很困于这项必须在今晚之前完成的作业。并且在作业不要使用“fs”模块的任何同步功能中也特别提到了这一点。那么我该如何做到这一点并牢记该条款呢?

PS:不要介意这些评论,我用它们来调试。

最佳答案

问题是你没有等待 fs.lstat()函数来完成每个文件。您正在排队所有 fs.lstat()调用,但随后不等待所有调用完成。你只要回来resultObj当它仍然[]时.

您可以通过在 data.forEach() 的回调中添加检查来解决此问题查看有多少项已回调 fs.lstat()调用。

listDir: (path, myCallback) => {
let resultObj = [];

fs.readdir(path, (err, data) => {
console.log('In listDir');
if (err) {
return myCallback(err);
}

let itemsCompleted = 0
data.forEach(value => {
fs.lstat(path + '/' + value, (err, stats) => {
itemsCompleted++
if (err) {
console.log(err);
} else {
if(stats.isFile() || stats.isDirectory()){
resultObj.push(value);
console.log(resultObj+'\n');
}
}

if(itemsCompleted >= data.length) {
return myCallback(null, resultObj)
}
});
});
}

但是,上述方法仍然比 Promises with async/await 更复杂。 。与async/await的 promise 是目前在 Node.js 中处理异步控制流的首选方法。利用 util.promisify() promise fs.readdir()fs.lstat()使我们能够扁平化控制流程并显着提高 listDir() 的可读性。此外,通过使用map()而不是forEach()我们可以使用Promise.all()包装从 lstatAsync() 返回的 Promise对于每个条目。

const {promisify} = require('util')
const fs = require('fs')
const {join} = require('path')
const readdirAsync = promisify(fs.readdir)
const lstatAsync = promisify(fs.lstat)

module.exports = {
listDir: async path => {
let resultObj = [];

let entries = await readdirAsync(path)
console.log('In listDir');

await Promise.all(entries.map(async value => {
try {
let stats = await lstatAsync(join(path, value))

if(stats.isFile() || stats.isDirectory()){
resultObj.push(value);
console.log(resultObj+'\n');
}
} catch (err) {
console.log(err)
}
}))

return resultObj
}
}

关于javascript - 即使在 Node.js 中的回调函数之后,函数也会异步运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48272330/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com