Angular $resource请求取消实现:基于$q的重复请求处理问询
实现请求取消:仅保留最后一次调用的请求
刚好我之前做过类似的需求,用Angular的$q.defer()完全能实现这个「重复调用只保留最后一次请求」的功能,给你捋捋具体怎么搞:
核心思路其实很简单:每次调用请求方法时,先把上一次还在pending状态的请求取消掉,再发起新的请求。具体步骤和代码示例如下:
- 第一步,在你的服务里声明一个变量,用来存储上一次请求对应的defer对象,比如
lastRequestDefer - 第二步,每次调用请求方法时,先检查这个变量是否存在:如果存在,就调用它的
reject()方法取消上一次请求 - 第三步,创建新的defer对象,把它赋值给
lastRequestDefer,然后发起HTTP请求 - 第四步,请求完成(成功或失败)后,记得把
lastRequestDefer重置为null,避免影响下一次调用
下面是完整的代码示例:
angular.module('yourApp').service('YourDataService', function($q, $http) { // 存储上一次请求的defer对象 let lastRequestDefer = null; this.fetchData = function(requestParams) { // 取消上一次未完成的请求 if (lastRequestDefer) { lastRequestDefer.reject('请求被取消:已发起新的请求'); lastRequestDefer = null; } // 创建当前请求的defer对象 const currentDefer = $q.defer(); lastRequestDefer = currentDefer; // 发起HTTP请求 $http.get('/api/your-data', { params: requestParams }) .then(function(response) { // 请求成功,resolve结果 currentDefer.resolve(response.data); }) .catch(function(error) { // 区分主动取消的错误和其他业务错误 if (error !== '请求被取消:已发起新的请求') { currentDefer.reject(error); } }) .finally(function() { // 只有当前请求是最后一次时,才清空defer变量 if (lastRequestDefer === currentDefer) { lastRequestDefer = null; } }); // 返回当前请求的promise return currentDefer.promise; }; });
额外补充几个注意点:
- 在catch分支里区分取消错误,可以避免把「主动取消」当成真正的错误提示给用户,提升体验
- 用finally来重置defer对象,能确保无论请求成功还是失败,都能及时清理变量,防止内存泄漏
- 如果你的项目用的是Angular 1.5+,其实也可以用
$http自带的取消功能($cancelRequest),不过用$q.defer()的方式兼容性更好,也更直观
内容的提问来源于stack exchange,提问作者Fede Menseguez
相关产品推荐
相关产品推荐

