使用download包下载图片时,捕获异常后重启程序出现无限循环的解决方案
解决图片下载无限循环的问题
我来帮你分析下为啥会出现无限循环的情况:
你的代码里每次调用runingImage()时,都是从原数组里随机选一个URL——如果刚好连续随机到那张损坏的图片,就会不断触发catch分支,然后递归调用runingImage(),运气不好的话就会一直选中坏图,陷入无限循环。另外还有个小问题:options变量没有用let/const声明,会变成全局变量,这可能带来意外的副作用。
下面给你两个可行的解决方案:
方案一:移除已确认损坏的URL
把下载失败的URL从数组里删掉,这样后续就不会再选到它,自然不会无限循环了:
let imgArrays = ["https://upload.wikimedia.org/wikipedia/commons/d/dc/Gigi1.jpg", "https://mms.businesswire.com/media/20211119005773/fr/929256/5/Aries_Linden_mechanical_completion_11-19-2021.jpg"] const runingImage = () => { // 如果数组为空,说明所有URL都失败了,直接退出 if (imgArrays.length === 0) { console.log("所有图片URL都无法下载"); return; } const randomIndex = Math.floor(imgArrays.length * Math.random()); const url = imgArrays[randomIndex]; const path = 'img/image.jpg' // 声明options为局部变量,避免全局污染 const options = { url: url, dest: path } download.image(options) .then(({ filename }) => { console.log('Saved to', filename) }).catch( (err) => { console.log("下载失败,移除该URL并重试"); // 从数组中移除失败的URL imgArrays.splice(randomIndex, 1); // 继续尝试剩下的URL return runingImage(); }) } runingImage();
方案二:添加重试次数限制
如果不想移除URL,而是希望限制重试的次数,避免无限循环,可以加一个计数器:
let imgArrays = ["https://upload.wikimedia.org/wikipedia/commons/d/dc/Gigi1.jpg", "https://mms.businesswire.com/media/20211119005773/fr/929256/5/Aries_Linden_mechanical_completion_11-19-2021.jpg"] // 自定义最大重试次数 const MAX_RETRIES = 5; let retryCount = 0; const runingImage = () => { if (retryCount >= MAX_RETRIES) { console.log("达到最大重试次数,停止下载"); return; } const url = imgArrays[Math.floor(imgArrays.length * Math.random())]; const path = 'img/image.jpg' const options = { url: url, dest: path } download.image(options) .then(({ filename }) => { console.log('Saved to', filename) // 成功后重置重试计数器 retryCount = 0; }).catch( (err) => { retryCount++; console.log(`下载失败,第${retryCount}次重试`); return runingImage(); }) } runingImage();
这样修改后,就不会出现无限循环的情况了,你可以根据自己的需求选择合适的方案~
内容的提问来源于stack exchange,提问作者cyruslk




