如何实现带时间间隔的Promise.all式批量Imgur图片上传?
实现带间隔的串行批量上传并保留Promise.all风格的响应格式
要实现每两次上传间隔1秒,同时保留Promise.all的.then((responseArray) => ...)响应格式,核心思路是串行执行上传任务,每次任务(除第一个)执行前等待指定间隔,最后收集所有结果返回一个Promise。以下是两种可行的实现方式:
方式一:使用Promise.reduce构建链式调用
这种方式通过Array.reduce逐步构建Promise链,自动收集每个上传任务的结果:
1. 定义延迟工具函数
// 返回一个延迟指定毫秒的Promise const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
2. 实现带间隔的上传函数
/** * 带间隔的串行批量上传函数 * @param {Function[]} uploadTasks - 上传任务数组,每个元素是返回Promise的上传函数 * @param {number} intervalMs - 两次上传之间的间隔毫秒数 * @returns {Promise<any[]>} 返回包含所有上传结果的Promise */ function uploadWithInterval(uploadTasks, intervalMs) { return uploadTasks.reduce((promiseChain, task, index) => { return promiseChain // 非第一个任务,先等待间隔 .then(results => index > 0 ? delay(intervalMs).then(() => results) : results) // 执行当前上传任务并收集结果 .then(results => task().then(response => [...results, response])); }, Promise.resolve([])); // 初始Promise,结果数组为空 }
3. 使用示例
假设listOf20Tasks是包含20个上传任务的数组(每个任务是返回Promise的函数,比如调用Imgur上传API的函数):
uploadWithInterval(listOf20Tasks, 1000) .then(responseArray => { // 这里拿到和任务顺序一致的所有上传结果数组,和Promise.all的响应格式完全一致 console.log('全部上传完成:', responseArray); }) .catch(error => { // 任何一个上传失败都会触发这里,和Promise.all的错误行为一致 console.error('上传失败:', error); });
方式二:使用async/await循环(更直观)
利用async/await的串行特性,循环执行任务并收集结果:
async function uploadWithInterval(uploadTasks, intervalMs) { const responseArray = []; for (let i = 0; i < uploadTasks.length; i++) { // 不是第一个任务,先等待间隔 if (i > 0) { await delay(intervalMs); } // 执行当前上传任务并保存结果 const response = await uploadTasks[i](); responseArray.push(response); } // 返回结果数组,async函数会自动包装为Promise return responseArray; }
使用方式和上面完全相同,因为async函数返回的就是Promise,所以可以直接用.then拿到结果数组。
可选:容错处理(类似Promise.allSettled)
如果希望某个上传失败时不中断整个流程,而是继续执行后续任务并记录错误,可以修改上传任务的错误处理:
// 在执行task时添加catch,将错误存入结果数组 .then(results => task() .then(response => [...results, { success: true, data: response }]) .catch(error => [...results, { success: false, error }]) )
这样最终的responseArray会包含每个任务的成功/失败状态,不会因为单个任务失败而reject。
内容的提问来源于stack exchange,提问作者Bhuwan Adhikari
相关产品推荐
相关产品推荐

