AngularJS中如何使用$promise实现异步调用并等待所有请求完成?
问题根因
for循环本身是同步执行的,发起API请求后不会等待异步响应返回,就会直接执行循环外的代码,因此拿不到拼接完成的res。你用async/await触发的regeneratorRuntime is not defined报错,是因为当前项目构建配置没有包含async/await的编译运行时,在不能新增依赖的前提下,直接用AngularJS内置的$q服务就能实现需求,不需要额外引入任何包。
解决方案
AngularJS原生内置了$q Promise处理服务,其中$q.all()方法可以接收一个Promise数组,等数组内所有Promise都执行完成后,才会触发自身的回调,正好匹配你的需求。
实现步骤
- 首先在对应的控制器/指令中注入
$q服务,该服务是AngularJS自带能力,无需额外安装依赖 - 初始化存储所有请求Promise的数组,同时给结果变量
res设置初始空值,避免拼接时出现undefined前缀 - 循环发起请求时,把每个请求对应的
$promise存到数组中,同时在每个Promise的回调里完成结果拼接 - 调用
$q.all()传入收集好的Promise数组,在它的回调中编写所有请求完成后要执行的业务逻辑
修改后的代码示例
// 注意先在控制器注入$q,示例:app.controller('yourCtrl', function($scope, MyService, $q) { $scope.myFunction = function() { let res = ''; // 初始化为空字符串,避免拼接出undefined前缀 const promiseList = []; // 存储所有请求的promise对象 for (/* 替换为你原有的循环条件 */) { const data = MyService.query(); // 绑定当前请求的结果处理逻辑,同时把promise存入收集列表 const currentPromise = data.$promise.then(function(r){ res += r.someValue; }); promiseList.push(currentPromise); } // 所有请求完成后才会执行这里的逻辑 $q.all(promiseList).then(function() { // 此处res已经完成所有接口结果的拼接,可以直接使用 console.log('全部请求完成,最终拼接结果:', res); // 编写你需要执行的后续业务逻辑即可 }).catch(function(err) { // 可选:统一处理请求异常 console.error('接口请求异常', err); }); }
补充说明
- 该方案完全基于AngularJS内置能力实现,不需要新增任何npm依赖,也不需要使用async/await语法,不会触发
regeneratorRuntime is not defined报错 - 如果需要单独处理单个请求的错误,可以在每个请求的
then后链式调用catch做局部异常捕获,不会影响$q.all的整体状态监听 - 不要在循环中发起请求后不收集Promise对象,否则
$q.all无法感知每个请求的完成状态
内容的提问来源于stack exchange,提问作者user3174311
相关产品推荐
相关产品推荐

