Node.js中如何等待异步进程执行完毕后再继续执行后续代码?
问题原因与修复方案
核心问题
你的downloadAndSaveFiles函数虽然标记了async,但内部的https.get是回调式异步API,没有封装为Promise等待下载流程结束,函数会在发起请求后立刻返回true,外层的await无法捕获到下载的异步流程,导致后续逻辑提前执行。
同时你的代码还存在两个潜在问题:
- 缺少错误监听:
https.get请求报错、文件流写入报错都没有捕获,上层try/catch无法处理这类异常 - 未声明的全局变量:
mediaUrl、thumbnailUrl、pageAccessToken等变量没有加let/const声明,会变成全局变量引发污染
修复代码
1. 重写downloadAndSaveFiles,封装为Promise
// 不需要加async,直接返回Promise即可 const downloadAndSaveFiles = ({ url, dir }) => { return new Promise((resolve, reject) => { https.get(url, (res) => { console.log('dir: ', dir); const filePath = fs.createWriteStream(dir); res.pipe(filePath); filePath.on('finish', () => { filePath.close(); console.log('Download Completed'); resolve(true); }); // 监听文件写入错误 filePath.on('error', (err) => { // 写入失败删除不完整的临时文件 fs.unlink(dir, () => reject(err)); }); }).on('error', (err) => { // 监听HTTP请求错误 reject(err); }); }); };
2. 可选优化:并行下载提升速度
你当前的写法是先下载媒体文件再下载缩略图,属于串行执行,可以修改为并行下载减少等待时间:
const downloadFiles = async ({ data }) => { try { // 补全变量声明 const mediaUrl = data.mediaUrl; const thumbnailUrl = data.thumbnailUrl; const mediaExt = path.extname(mediaUrl); const thumbExt = path.extname(thumbnailUrl); const mediaDir = `${__dirname}/temp/media${mediaExt}`; const thumbDir = `${__dirname}/temp/thumb${thumbExt}`; // 并行发起两个下载请求,全部完成后才会继续执行 await Promise.all([ downloadAndSaveFiles({ url: mediaUrl, dir: mediaDir }), downloadAndSaveFiles({ url: thumbnailUrl, dir: thumbDir }) ]); return { mediaDir, thumbDir }; } catch (e) { console.log(e); throw e; } };
修改完成后,await downloadFiles就会等待所有文件下载存储完成后,再执行后续的上传引擎逻辑。
内容的提问来源于stack exchange,提问作者Adarsh Bhadauria
相关产品推荐
相关产品推荐

