JS 利用Promise.all 简单实现多任务并行

本文介绍了一个使用Promise实现的批量任务处理函数functionTaskWaitAll,该函数可以接受多个回调函数作为参数,将它们转换为Promise,并使用Promise.all等待所有任务完成。示例展示了如何使用此函数并行执行三个任务,最后通过.then()获取所有任务的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       function TaskWaitAll() {
            function timerPromisefy(func) {
                return new Promise(function (resolve, reject) {
                    func(resolve, reject);
                });
            }
            var taskall = [];
            for (var i = 0; i < arguments.length; i++) {
                taskall.push(timerPromisefy(arguments[i]));
            }
            return Promise.all(taskall);
        }

使用起来非常方便

    TaskWaitAll(function (resolve) {
        resolve(1);
    },function (resolve) {
        resolve(2);
    },function (resolve) {
        resolve(3);
    }).then(function (results){
        console.log(results);//打印出来等于[1,2,3]
    });

 

<think>好的,用户想知道如何使用Promise.all实现文件或其他资源的并行上传。首先,我需要回忆一下Promise.all的基本用法。Promise.all可以将多个Promise实例包装成一个新的Promise实例,当所有传入的Promise都成功时,才会触发成功,如果其中一个失败,就会立即失败。这对于并行处理多个异步操作非常有用,比如文件上传。 接下来,用户需要的是最佳实践和示例代码。所以,我需要考虑几个方面:错误处理、并发控制、进度追踪以及取消功能。首先,错误处理是关键。因为Promise.all有一个特性,就是如果其中一个Promise被拒绝,整个Promise.all会立即被拒绝。这可能不是用户想要的,特别是在上传多个文件时,可能希望即使某个文件上传失败,其他文件仍然继续上传。这时候可能需要使用Promise.allSettled来代替,或者在上传函数内部处理错误,确保每个上传的Promise始终resolve,但返回一个带有状态的对象。 然后,并发控制。虽然Promise.all可以并行启动所有上传任务,但如果同时上传太多文件,可能会遇到浏览器或服务器的限制。这时候可能需要限制并发数,比如使用第三方库如p-limit,或者自己实现一个并发队列。不过用户的问题可能更关注基础用法,所以可以先提供基本的Promise.all示例,再提到并发控制的优化方案。 进度追踪也是一个常见需求。用户可能想知道每个文件的上传进度,这时候可以在每个上传的Promise中添加进度事件监听器,并通过回调函数或者事件来更新进度。示例代码中需要展示如何将XMLHttpRequest或fetch API与Promise结合,同时处理进度事件。 取消功能的话,AbortController是一个现代浏览器支持的API,可以用来取消上传请求。在示例中,可以为每个上传任务创建一个AbortController实例,并将其signal传递给fetch的选项。这样,用户可以在需要时调用abort()方法取消所有上传。 接下来,我需要组织这些思路,给出结构清晰的回答。首先介绍基本实现,展示使用Promise.all的代码示例,然后讨论错误处理的改进,比如使用Promise.allSettled。接着提到并发控制的问题和可能的解决方案。然后展示如何添加进度追踪,最后介绍取消功能的使用。 在代码示例方面,可能需要使用fetch API,因为它是现代JavaScript中常用的方法。对于每个文件的上传,可以创建一个FormData对象,将文件附加进去,然后使用fetch发送POST请求。同时,为了跟踪进度,可能需要使用XMLHttpRequest,因为fetch目前不支持进度事件。不过这样会使得代码稍微复杂一些,需要将XHR包装成Promise。 或者,可以展示两种方式:一种使用fetch,另一种使用XHR来处理进度。但可能更倾向于使用XHR来展示进度追踪,尽管代码会稍微冗长,但更直观。 另外,示例代码需要包括错误处理,比如catch块,或者在每个上传函数中处理错误,确保Promise.all不会因为单个失败而全部失败。 最后,生成相关问题,可能需要包括Promise.all与其他并发控制方法的比较、错误处理的最佳实践、进度追踪的其他方法,以及取消上传的实现细节等。 总结一下,回答的结构应该是: 1. 基本实现:使用Promise.all和fetch上传多个文件。 2. 错误处理改进:使用Promise.allSettled或封装错误。 3. 并发控制:使用p-limit库限制并发数。 4. 进度追踪:通过XHR的progress事件。 5. 取消功能:AbortController的使用。 6. 示例代码展示这些部分。 7. 相关问题。 需要确保代码正确,语法正确,并且注释清晰。同时,引用可能需要来自MDN或其他可靠资源,但用户没有提供引用源,所以可能不需要添加具体的引用标识,但如果有必要的话,可以提到相关文档。</think>### 通过Promise.all实现并行上传的最佳实践 #### 1. 基本实现原理 `Promise.all` 可同时发起多个异步任务,当所有上传任务完成后返回统一结果。以下为使用`fetch API`实现的基础示例: ```javascript // 单个文件上传函数 function uploadFile(file, url) { const formData = new FormData(); formData.append('file', file); return fetch(url, { method: 'POST', body: formData }); } // 并行上传所有文件 async function parallelUpload(files, apiUrl) { try { const uploadPromises = files.map(file => uploadFile(file, apiUrl)); const results = await Promise.all(uploadPromises); console.log('所有文件上传成功', results); } catch (error) { console.error('至少一个文件上传失败', error); } } ``` #### 2. 错误处理优化 使用 `Promise.allSettled` 可确保部分失败不影响整体流程: ```javascript const results = await Promise.allSettled(uploadPromises); const successfulUploads = results.filter(r => r.status === 'fulfilled'); ``` #### 3. 并发控制(防止资源耗尽) 通过 `p-limit` 库实现并发限制: ```javascript import pLimit from 'p-limit'; const limit = pLimit(3); // 最大并发数3 const controlledUpload = files.map(file => limit(() => uploadFile(file, apiUrl)) ); await Promise.all(controlledUpload); ``` #### 4. 进度追踪实现 通过XMLHttpRequest实现进度监控: ```javascript function uploadWithProgress(file, url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); const formData = new FormData(); formData.append('file', file); xhr.upload.addEventListener('progress', e => { if (e.lengthComputable) { const percent = (e.loaded / e.total) * 100; console.log(`${file.name} 上传进度: ${percent.toFixed(2)}%`); } }); xhr.open('POST', url); xhr.onload = () => resolve(xhr.response); xhr.onerror = () => reject(xhr.statusText); xhr.send(formData); }); } ``` #### 5. 取消上传功能 使用AbortController实现请求终止: ```javascript const controller = new AbortController(); function uploadWithAbort(file, url) { return fetch(url, { method: 'POST', body: formData, signal: controller.signal // 绑定中止信号 }); } // 点击取消按钮时调用 document.getElementById('cancelBtn').addEventListener('click', () => { controller.abort(); }); ``` ### 关键注意事项 - 服务端需支持并行处理请求 - 大文件上传建议分片处理 - 浏览器并发请求数存在限制(Chrome默认6个)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值