Node.js中Promise.all的then回调无法触发问题求助
问题分析与修复
你的代码能输出文件路径但触发不了task_ended,核心原因是每个Promise都没有调用resolve()或reject(),导致所有Promise一直处于pending(等待)状态,Promise.all永远无法判定所有任务完成,自然不会进入then执行结束函数。
另外代码还有几个细节问题需要调整:
getDirectories没有用const/let声明,会变成全局变量,可能引发意外问题- 循环里的
i是全局变量,遍历多个目录时会出现变量污染 - 可以直接让glob匹配
content.txt,不用遍历所有文件再判断,更高效
修正后的代码
const fs = require("fs"); const glob = require("glob"); function getDirectoryName(dir) { return dir; } const startDir = getDirectoryName('compliance_finish'); const directoryFiles = fs.readdirSync(`../${startDir}`); Promise.all( directoryFiles.map((filename) => { return new Promise((resolve, reject) => { // 直接用glob匹配content.txt,不用遍历所有文件 glob(`../${startDir}/${filename}/**/content.txt`, (err, res) => { if (err) { console.log('Error', err); reject(err); // 出错时调用reject,标记Promise失败 return; } // 找到的文件路径,这里假设每个目录下只有一个content.txt const pat2 = res[0]; if (pat2) { console.log(pat2); } resolve(pat2); // 处理完成后调用resolve,标记Promise完成 }) }) }) ).then((allPaths) => { console.log('所有文件路径:', allPaths); task_ended(); }).catch((err) => { console.log('任务出错:', err); }) function task_ended(){ console.log('finished') }
关键修改点说明
- 调用resolve/reject:在glob的回调里,成功时调用
resolve()传递结果,出错时调用reject()传递错误,让Promise状态更新,Promise.all能感知任务完成。 - 优化glob匹配:直接使用
../${startDir}/${filename}/**/content.txt作为匹配模式,glob会直接返回所有符合条件的文件,省去手动遍历判断的步骤。 - 修复变量作用域:移除不必要的
getDirectories函数,避免全局变量;确保所有变量都有正确的声明(比如原本的循环变量问题也通过直接取res[0]避免了)。 - 添加catch处理:给
Promise.all添加catch回调,处理可能出现的错误,避免静默失败。
内容的提问来源于stack exchange,提问作者Rmcguirk
相关产品推荐
相关产品推荐

