JavaScript中如何正确触发async.map的结果回调?
问题根因
你的async.map最终回调未触发的核心原因是迭代函数counter的callback没有覆盖所有执行路径:
async.map要求每一个迭代任务都必须显式调用传入的callback函数,才会在所有任务完成后触发最终的回调。- 你当前的代码里,只有当路径判断为文件(
result.isFile() === true)时才调用了callback;如果目标路径是目录,就不会执行任何callback调用,相当于async.map一直处于等待剩余任务返回的状态,自然不会执行最终的回调。
修复方案
你只需要补齐counter函数的callback调用即可,如果需求仅统计当前目录下直接文件的总大小,目录项可以按大小0处理,同时建议把异步错误传递给callback而非直接throw,更符合async库的错误处理规范:
import path from 'path'; import fs from 'fs'; import async from 'async'; export const getDirectorySize = (directory) => { fs.readdir(directory, (error, files) => { if (error) throw error; const counter = (el, callback) => { fs.stat(path.join(directory, el), (error2, result) => { // 把错误传给callback,由async统一传递到最终回调处理 if (error2) return callback(error2); if (result.isFile()) { return callback(null, result.size); } // 非文件类型(目录/软链接等)按0大小处理,必须调用callback return callback(null, 0); }); } async.map(files, counter, (error3, results) => { if (error3) throw error3; const totalSize = results.reduce((prev, current) => prev + current, 0); console.log(totalSize); // 如果需要对外返回结果,可以在这里调用外层传入的回调函数返回totalSize }); }); } getDirectorySize('/usr/src/app');
额外说明
如果你需要递归统计所有子目录内的文件总大小,只需要在判断为目录时,递归调用getDirectorySize获取子目录总大小,再通过callback返回即可。
内容的提问来源于stack exchange,提问作者Yuri Molodyko
相关产品推荐
相关产品推荐

