使用 npm exiftool (javascript) 异步问题
using npm exiftool (javascript) async problem
我在使用 npm exiftool 时遇到问题。 (https://www.npmjs.com/package/exiftool)我正在尝试使用它做一些事情。
- 通过特定文件夹迭代图像文件
- 获取每个图像文件的'xpKeywords'个数据。
- 写文件存储数据。
这是我的代码。
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 中使用异步函数时遇到了一些问题。
那里有几个问题。
- 最主要的是
getMetaData
没有 return 任何东西。从您提供的 回调 返回 exif.metadata
不会执行任何操作来设置 getMetaData
. 的 return 值
- 另外,
fs.readFileSync
没有 return 承诺,因此 let results = await Promise.all(promises);
调用没有意义。 (顾名思义,它同步工作。)
- 通过索引将文件引用到全局模块中很容易出错。
要使用 promises,您可以在 fs.readFile
上使用 Node.js 的当前实验性 promises file API, or use util.promisify
(该版本实际上是异步的,使用回调)。如果您想获得启用承诺的版本,也可以在 exif.metadata
上使用 promisify
。
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);
});
我在使用 npm exiftool 时遇到问题。 (https://www.npmjs.com/package/exiftool)我正在尝试使用它做一些事情。
- 通过特定文件夹迭代图像文件
- 获取每个图像文件的'xpKeywords'个数据。
- 写文件存储数据。
这是我的代码。
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 中使用异步函数时遇到了一些问题。
那里有几个问题。
- 最主要的是
getMetaData
没有 return 任何东西。从您提供的 回调 返回exif.metadata
不会执行任何操作来设置getMetaData
. 的 return 值
- 另外,
fs.readFileSync
没有 return 承诺,因此let results = await Promise.all(promises);
调用没有意义。 (顾名思义,它同步工作。) - 通过索引将文件引用到全局模块中很容易出错。
要使用 promises,您可以在 fs.readFile
上使用 Node.js 的当前实验性 promises file API, or use util.promisify
(该版本实际上是异步的,使用回调)。如果您想获得启用承诺的版本,也可以在 exif.metadata
上使用 promisify
。
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);
});