AngularJS中forEach结合$q.all批量上传文件未等待全部完成问题
看起来你的问题出在promises数组没有正确收集每个文件的异步上传任务,加上deferred对象没有在上传完成时正确调用resolve/reject,才导致$q.all误以为第一个文件完成就全部结束了。我帮你修正代码并拆解关键点:
问题根源分析
从你给出的代码片段看,至少有两个明显问题:
promises.push(deferred)被注释了,导致$q.all根本没收到后续文件的上传任务- 即使没注释,你push的是
deferred对象而非它的promise属性,$q.all无法正确追踪异步状态 - 缺少上传完成后对deferred的resolve/reject操作,promise永远处于pending状态
修正后的完整代码
factory.UploadFilesByBatch = function(arrayBuffer, folderName) { var promises = []; // 先统一获取SharePoint的FormDigest(避免每个文件重复请求) return factory.GetFormDigest().then(function(formDigestValue) { // 遍历所有待上传文件 angular.forEach(arrayBuffer, function(item) { var deferred = $q.defer(); // 把当前文件的上传promise加入追踪数组 promises.push(deferred.promise); console.log(`开始上传文件: ${item.fileName}`); // 发起SharePoint文件上传请求 $http({ method: 'POST', url: `/_api/web/getfolderbyserverrelativeurl('${folderName}')/files/add(overwrite=true,url='${item.fileName}')`, headers: { 'Accept': 'application/json;odata=verbose', 'X-RequestDigest': formDigestValue, 'Content-Type': item.fileType // 要匹配文件的MIME类型 }, data: item.arrayBuffer // 传入文件的ArrayBuffer数据 }).then(function(response) { console.log(`文件 ${item.fileName} 上传成功`); // 上传成功,标记当前promise完成 deferred.resolve(response.data); }).catch(function(error) { console.error(`文件 ${item.fileName} 上传失败`, error); // 上传失败,标记当前promise失败 deferred.reject(error); }); }); // 等待所有上传任务完成 return $q.all(promises); }); };
关键注意事项
- 统一获取FormDigest:SharePoint的FormDigest有效期足够处理批量上传,无需每个文件都请求一次,既提升效率又避免重复请求
- 正确收集promise:必须将
deferred.promise加入数组,而非deferred对象本身——$q.all只能识别promise对象的状态 - 必须收尾promise:在$http的成功/失败回调里一定要调用
deferred.resolve()或deferred.reject(),否则该promise会一直处于pending状态,$q.all永远不会触发完成 - 返回最终promise:整个函数返回$q.all的结果,这样调用方可以直接用then/catch处理全部上传完成或失败的逻辑
调用示例
// 假设你已经收集好文件的arrayBuffer、文件名、类型组成的数组 factory.UploadFilesByBatch(yourFileArray, 'Shared Documents/批量上传文件夹') .then(function(allUploadResults) { alert('所有文件上传完成!'); console.log('每个文件的上传结果:', allUploadResults); }) .catch(function(error) { alert('至少有一个文件上传失败,请检查日志'); console.error('上传失败详情:', error); });
内容的提问来源于stack exchange,提问作者Hawk
相关产品推荐
相关产品推荐

