AngularJS Promise链式调用中service的catch执行后controller的then仍触发?
问题根因分析
核心是service.ts里的someMethod存在两处逻辑错误,导致最终返回给controller的promise状态是已解决(resolved):
- 错误1:返回了错误的Promise对象
你在someMethod内部手动创建了deferred对象,但最终没有返回deferred.promise,而是直接返回了OtherService.otherMethod()的链式调用结果。你在catch里执行的deferred.reject(reason)完全没有作用,因为这个deferred对象的promise从来没有被返回给调用方。 - 错误2:catch回调没有返回rejected状态的Promise
Promise的catch回调如果没有主动抛出错误、或者返回一个rejected状态的Promise,那么catch执行完成后会默认返回一个resolved状态的Promise,链式调用就会走到后续的then分支。你当前someMethod里的catch只执行了无意义的deferred.reject(reason),没有做任何中断resolve的操作,所以最终返回给controller的Promise是resolved状态,自然会走到then块。
修复方案
两种修复方式二选一即可:
方案1:删除冗余deferred,直接在catch里返回rejected状态
someMethod(): ng.IPromise<void> { return this.OtherService.otherMethod() .catch ( e => { // 主动抛出错误,让链式调用返回rejected状态 throw e; // 也可选择用$q返回rejected:return this.$q.reject(e); }); }
方案2:保留deferred写法,返回正确的promise对象
someMethod(): ng.IPromise<void> { const deferred = this.$q.defer<void>(); this.OtherService.otherMethod() .then(() => deferred.resolve()) .catch ( e => { deferred.reject(e); }); // 此处必须返回手动创建的deferred对应的promise return deferred.promise; }
内容的提问来源于stack exchange,提问作者Luciano Borges
相关产品推荐
相关产品推荐

