Node.js使用axios批量下载图片数组时仅成功下载第一张图片
问题根因
你写的return new Promise(...)放在了for循环体内部,第一次循环(处理arr[0])执行到这行时,会直接终止整个downloadImage异步函数的执行,把Promise返回出去,后续的数组元素根本不会进入循环逻辑,所以只会下载第一张图。
另外现有逻辑还有两个隐藏问题:
- 没有等当前图片的写入流完全结束就推进流程,容易出现文件损坏、资源泄漏
- 目录创建、流写入环节没有错误捕获,出问题时不会抛错很难排查
修正后可直接运行的代码
const Fs = require('fs') const Path = require('path') const Axios = require('axios') const dir = './tmp'; async function downloadImage () { // 先确保下载目录存在 if (!Fs.existsSync(dir)){ Fs.mkdirSync(dir, { recursive: true }); } const arr = [ 'https://reaperscans.com/wp-content/uploads/WP-manga/data/manga_6295b8da2aa90/5461fc34b58cd174c806625056c6e0dc/01-copy.jpg', 'https://reaperscans.com/wp-content/uploads/WP-manga/data/manga_6295b8da2aa90/5461fc34b58cd174c806625056c6e0dc/02-copy.jpg', 'https://reaperscans.com/wp-content/uploads/WP-manga/data/manga_6295b8da2aa90/5461fc34b58cd174c806625056c6e0dc/03-copy.jpg' ] for(let i = 0; i < arr.length; i++){ const url = arr[i] const name = `${i}.jpg` const savePath = Path.resolve(__dirname, dir, name) const writer = Fs.createWriteStream(savePath) const response = await Axios({ url, method: 'GET', responseType: 'stream' }) // 等当前文件完全写入完成再进下一轮循环 await new Promise((resolve, reject) => { response.data.pipe(writer) writer.on('finish', resolve) writer.on('error', reject) response.data.on('error', reject) }) console.log(`第${i+1}张图片下载完成`) } console.log('所有图片下载完成') } downloadImage().catch(err => { console.error('下载出错:', err) })
改动点说明
- 移除了循环内提前终止函数的
return,改为用await等待单张图片下载、写入全流程完成后再进入下一轮循环,保证所有数组元素都能被处理 - 给
mkdirSync加了recursive: true参数,避免多级目录不存在时报错 - 给请求流也加了错误监听,避免请求出错时进程卡住无响应
- 给
downloadImage()调用加了catch捕获,下载过程中任何错误都会正常抛出,方便排查问题
内容的提问来源于stack exchange,提问作者how is this
相关产品推荐
相关产品推荐

