AngularJS函数触发重复请求问题:一次无结果一次返回有效结果
看起来你遇到的重复请求问题在AngularJS里挺常见的,虽然你排除了重复控制器的可能,但还有几个常见的排查方向,咱们一步步来捋:
第一步:先确认submit函数是不是被调用了两次
先在你的submit函数开头加一行日志,看看它的调用次数:
PanelCtrl.prototype.submit = function(data) { console.log('submit函数被调用了!当前数据:', data); // 加这行日志 service.create(data).then(function(result){ if(result.success === true) { service.add... } }); }
打开浏览器控制台,点击“添加”按钮后看日志:
- 如果日志打印了两次,说明触发submit的逻辑重复了;
- 如果只打印一次,那问题出在
service.create内部或者HTTP请求层面。
如果submit被调用了两次:检查弹窗的事件绑定
虽然你觉得和md-dialog无关,但弹窗的按钮很容易出现重复绑定的情况:
模板与控制器的双重绑定:比如模板里按钮用了
ng-click="vm.submit(data)",同时你在控制器里又用原生JS/jQuery绑定了点击事件:// 控制器里的错误代码示例 angular.element('#addBtn').on('click', () => { this.submit(this.data); });这种情况点击一次会触发两次submit,删掉其中一个绑定就行。
md-dialog的内置回调与自定义点击冲突:如果你在打开dialog时设置了
ok回调,同时按钮上又加了ng-click:// 打开dialog的错误代码示例 $mdDialog.show({ templateUrl: 'your-dialog.html', controller: PanelCtrl, controllerAs: 'vm', ok: () => { vm.submit(vm.data); // 这里调用一次 } });而模板里的按钮又写了
<md-button ng-click="vm.submit(data)" md-dialog-ok>添加</md-button>,这就会触发两次submit,去掉其中一个逻辑即可。
如果submit只被调用一次:检查service.create的实现
这种情况大概率是service.create内部重复发送了请求,或者HTTP层面有重试逻辑:
service内部重复调用$http:比如你的
create方法里不小心写了两次请求:// service的错误代码示例 function create(data) { $http.post('/api/create', data); // 多余的一次请求 return $http.post('/api/create', data); }检查一下
service.create的代码,确保只返回一个$http promise。HTTP拦截器导致的重复请求:如果项目里配置了$http拦截器,看看是不是拦截器里不小心重复发送了请求:
// 拦截器的错误代码示例 $httpProvider.interceptors.push(function($q) { return { request: function(config) { $http(config); // 这里会额外发送一次请求 return config; } }; });请求自动重试机制:有没有在$http的配置里设置了重试?比如某些第三方库或者自定义逻辑在请求失败时自动重试,导致第一次请求失败(比如参数不完整),第二次重试成功。这种情况可以看Network面板里第一次请求的状态码(比如400、500),然后检查第一次发送的data是不是有问题。
额外排查点:表单验证与digest循环
如果你的弹窗里有表单,有没有可能第一次点击时表单未通过验证,但代码还是发送了请求,而第二次点击时表单数据已经正确?不过这种情况一般不会导致两次请求,除非你在表单的ng-change或者$watch里触发了submit。另外,检查submit函数里有没有修改scope变量导致digest循环再次触发,进而重复调用submit(这种情况比较少见,但可以留意)。
先按上面的步骤排查,应该能找到问题所在~
内容的提问来源于stack exchange,提问作者Tuz

