我在使用npm exiftool时遇到问题。 (https://www.npmjs.com/package/exiftool)我正在尝试使用它来做一些事情。
这是我的代码。
const fs = require('fs');
const exif = require('exiftool');
const folderName = 'testImages';
const inputPath = `/Users/myName/Project/project/${folderName}`;
const files = fs.readdirSync(inputPath, 'utf8');
let data = [];
(async () => {
let promises = [];
files.forEach(file => promises.push(fs.readFileSync(`${inputPath}/${file}`)));
let results = await Promise.all(promises);
for(let [index, result] of results.entries()) {
let datum = await getMetadata(result, index);
console.log("out");
data.push(datum);
}
fs.writeFileSync('outputData/metaData.json', JSON.stringify(data, null, 4), (error) => {
console.log('Error Occurred');
});
})();
async function getMetadata(result, index) {
console.log(`get metadata ${index}`);
await exif.metadata(result, (err, metadata) => {
return {
name: files[index],
hashTags: metadata.xpKeywords
};
});
}
运行该代码后,文件metaData.json不是我所期望的。
[ 空值, 空值, 空值, 空值, 空值, 空值 ]
我认为在getMetadata函数中使用异步函数遇到一些麻烦。
答案 0 :(得分:0)
那里有几个问题。
getMetaData
不返回任何内容。从回调中返回您提供的exif.metadata
对设置getMetaData
的返回值没有任何作用。fs.readFileSync
不会返回承诺,因此let results = await Promise.all(promises);
调用没有意义。 (顾名思义,它是同步工作。)要使用Promise,可以使用Node.js的当前实验promises file API,也可以在fs.readFile
上使用util.promisify
(实际上是异步的,使用回调的版本)。如果您要获得启用了承诺的版本,也可以在promisify
上使用exif.metadata
。
This question's answers详细介绍了如何将基于回调的API转换为promise。
牢记所有这些,我认为您正在寻找符合以下要求的内容(可能需要调整):
const fs = require('fs');
const {promisify} = require('util');
const exif = require('exiftool');
const pReaddir = promisify(fs.readdir);
const pReadFile = promisify(fs.readFile);
const pWriteFile = promisify(fs.writeFile);
const pMetadata = promisify(exif.metadata);
const folderName = 'testImages';
const inputPath = `/Users/myName/Project/project/${folderName}`;
(async () => {
// Get the file names
const files = await pReaddir(inputPath, 'utf8');
// Process the files in parallel and wait for the result
const data = Promise.all(files.map(async(name) => {
// Read this file and get its metadata from it
let {xpKeywords: hashTags} = await pMetadata(await pReadFile(`${inputPath}/${name}`));
// Return an object with the file's name and xpKeywords as its hashTags
return {name, hashTags};
}));
// Write the results to file
await pWriteFile('outputData/metaData.json', JSON.stringify(data, null, 4));
})()
.catch(error => {
console.error(error);
});