等待地图功能中的所有承诺
我想等一下,在地图功能中阅读我的所有照片
我试过这个
let buffer = [];
// Folder of the dataset.
const rootFolder = './dataset'
console.log("Entering in folder dataset");
fs.readdirSync(rootFolder);
// For each folders
const files = fs.readdirSync(rootFolder).map(dirName => {
if(fs.lstatSync(path.join(rootFolder, dirName)).isDirectory()){
console.log(`Entering in folder ${path.join(rootFolder, dirName)}`);
// For each files
fs.readdirSync(path.join(rootFolder, dirName)).map(picture => {
if(fs.lstatSync(path.join(rootFolder, dirName, picture)).isFile()){
if(picture.startsWith("norm")){
return fileToTensor(path.join(rootFolder, dirName, picture)).then((img) => {
buffer.push(img);
}).catch((error) => {console.log(error)});
}
}
});
}
});
Promise.all(files);
console.log(buffer);
async function fileToTensor(path) {
return await sharp(path)
.removeAlpha()
.raw()
.toBuffer({ resolveWithObject: true });
}
但我的缓冲区仍然是空的......
我知道承诺存在,但我不知道如何将它们包含在地图中(map())
谢谢 :)
回答如下:我会将上面的代码重构为:
let files = [];
// loop each dir.
fs.readdirSync(rootFolder).forEach(dirName => {
// if it's a directory, procede.
if(fs.lstatSync(path.join(rootFolder, dirName)).isDirectory()){
console.log(`Entering in folder ${path.join(rootFolder, dirName)}`);
fs.readdirSync(path.join(rootFolder, dirName)).forEach(picture => {
if(fs.lstatSync(path.join(rootFolder, dirName, picture)).isFile()){
// If lstatsync says it's a file and if it starts with "norm"
if(picture.startsWith("norm")){
// push a new promise to the array.
files.push(new Promise((resolve, reject) => {
fileToTensor(path.join(rootFolder, dirName, picture)).then((img) => {
buffer.push(img);
resolve();
}).catch((error) => {console.log(error); reject(error);});
}));
}
}
});
}
});
// Resolve all promises.
Promise.all(files).then(() => {
// Then do whatever you need to do.
console.log(buffer);
}).catch((errors) => {
console.log('one ore more errors occurred', errors);
});
基本上,这就是我所做的:
- 删除了
.map
,因为在这种情况下没有必要。此外,在您的情况下,并非所有代码路径都返回结果,因此并非每个回调都返回结果。 - 将每个需要的项目推送到文件数组,这是一个
Promise[]
。 - 在文件数组上调用
Promise.all
。每个已解决的承诺都会将结果推送到buffer
数组。我会以不同的方式处理它,但是,这是我能想到的最快的。 - 在
Promise.all
上注册回调,以便定义buffer
。
作为旁注,有很多第三方库可以帮助您避免嵌套循环并承诺循环文件系统。我刚刚发布了这个以尝试提供可以从现有代码实际工作的东西,尽管整个重构在这里会很聪明,并且对可用节点库的初步分析也有助于使代码更容易阅读和保持。
等待地图功能中的所有承诺
我想等一下,在地图功能中阅读我的所有照片
我试过这个
let buffer = [];
// Folder of the dataset.
const rootFolder = './dataset'
console.log("Entering in folder dataset");
fs.readdirSync(rootFolder);
// For each folders
const files = fs.readdirSync(rootFolder).map(dirName => {
if(fs.lstatSync(path.join(rootFolder, dirName)).isDirectory()){
console.log(`Entering in folder ${path.join(rootFolder, dirName)}`);
// For each files
fs.readdirSync(path.join(rootFolder, dirName)).map(picture => {
if(fs.lstatSync(path.join(rootFolder, dirName, picture)).isFile()){
if(picture.startsWith("norm")){
return fileToTensor(path.join(rootFolder, dirName, picture)).then((img) => {
buffer.push(img);
}).catch((error) => {console.log(error)});
}
}
});
}
});
Promise.all(files);
console.log(buffer);
async function fileToTensor(path) {
return await sharp(path)
.removeAlpha()
.raw()
.toBuffer({ resolveWithObject: true });
}
但我的缓冲区仍然是空的......
我知道承诺存在,但我不知道如何将它们包含在地图中(map())
谢谢 :)
回答如下:我会将上面的代码重构为:
let files = [];
// loop each dir.
fs.readdirSync(rootFolder).forEach(dirName => {
// if it's a directory, procede.
if(fs.lstatSync(path.join(rootFolder, dirName)).isDirectory()){
console.log(`Entering in folder ${path.join(rootFolder, dirName)}`);
fs.readdirSync(path.join(rootFolder, dirName)).forEach(picture => {
if(fs.lstatSync(path.join(rootFolder, dirName, picture)).isFile()){
// If lstatsync says it's a file and if it starts with "norm"
if(picture.startsWith("norm")){
// push a new promise to the array.
files.push(new Promise((resolve, reject) => {
fileToTensor(path.join(rootFolder, dirName, picture)).then((img) => {
buffer.push(img);
resolve();
}).catch((error) => {console.log(error); reject(error);});
}));
}
}
});
}
});
// Resolve all promises.
Promise.all(files).then(() => {
// Then do whatever you need to do.
console.log(buffer);
}).catch((errors) => {
console.log('one ore more errors occurred', errors);
});
基本上,这就是我所做的:
- 删除了
.map
,因为在这种情况下没有必要。此外,在您的情况下,并非所有代码路径都返回结果,因此并非每个回调都返回结果。 - 将每个需要的项目推送到文件数组,这是一个
Promise[]
。 - 在文件数组上调用
Promise.all
。每个已解决的承诺都会将结果推送到buffer
数组。我会以不同的方式处理它,但是,这是我能想到的最快的。 - 在
Promise.all
上注册回调,以便定义buffer
。
作为旁注,有很多第三方库可以帮助您避免嵌套循环并承诺循环文件系统。我刚刚发布了这个以尝试提供可以从现有代码实际工作的东西,尽管整个重构在这里会很聪明,并且对可用节点库的初步分析也有助于使代码更容易阅读和保持。