如何确保在数组forEach所有回调函数执行完成后, 执行接下来的步骤

背景是文件遍历并对每个文件执行操作
用同步遍历得到了每个文件的路径, 并保存在一个数组中
数组forEach传入函数, 使用了模块node-exiftool来读取每个文件(主要是图片)的信息, 这就创造了一堆的回调函数, 不断地链式.then操作
node-exiftool需要在信息读取结束后使用.then(() => ep.close())来结束程序
怎么判断所有的回调函数都完成了呢?

node-exiftool给出的示例

const exiftool = require('node-exiftool')
const ep = new exiftool.ExiftoolProcess()

ep
  .open()
  // display pid
  .then((pid) => console.log('Started exiftool process %s', pid))
  .then(() => ep.readMetadata('photo.jpg', ['-File:all']))
  .then(console.log, console.error)
  .then(() => ep.readMetadata('photo2.jpg', ['-File:all']))
  .then(console.log, console.error)
  .then(() => ep.close())
  .then(() => console.log('Closed exiftool'))
  .catch(console.error)

写成模块, 我把这个过程分成了三个步骤: 开启, 读取, 关闭

const exiftool = require('node-exiftool')
const exiftoolBin = require('dist-exiftool')
const ep = new exiftool.ExiftoolProcess(exiftoolBin)
exports.openExif = () => ep.open()
exports.getDate = (openedEp, path, cb) => {
    return openedEp
        .then(() => ep.readMetadata(path, ['charset filename=utf8', 'CreateDate']))
        .then(cb, console.error)
}
exports.closeExif = finishedEp => finishedEp.then(ep.close()).catch(console.error)

然后另一个文件调用该模块

let openedEP = exif.openExif()
fileArr.forEach((item) => {
    openedEp = exif.getDate(openedEP, item, handleDate)
    function handleDate(metadata) {
        let date = parse(metadata.data[0].CreateDate)
        console.log(path.basename(item) + ': ' + date.toJSON())
    }
})

控制台前两行输出

(node:11208) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 finish listeners added. Use emitter.setMaxListeners() to increase limit
(node:11208) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 finish listeners added. Use emitter.setMaxListeners() to increase limit

不知道是为什么
而且程序不会退出
图片描述

初学者, 求各位有经验的大大解答

阅读 7.2k
1 个回答

自己解决了, 还是对promise的知识理解不足
把所有的promise装起来, 最后Promise.all包裹一下就行了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题