【问题标题】:Prevent previous, yet longer-running $http request from returning after most recent request防止在最近的请求之后返回先前但运行时间较长的 $http 请求
【发布时间】:2016-01-30 02:10:36
【问题描述】:

我刚刚遇到了一个奇怪的情况,经过一番搜索后无法找到答案。

我有一个文本框,允许用户输入关键字来过滤表数据。我在输入元素上有一个ng-change 指令,它将触发此代码:

return $http.get(url).then(function (response) {
    return response.data;
});

所有这些都运行良好,直到我们的测试人员在 IE11 中发现了一些不良行为。以下是在 IE10 的文本框中输入“M-A-T-T”的示例:

如您所见,每个后续请求都比第一个请求花费更长的时间,因此第四个也是最后一个请求的结果是控制器收到的结果。

这是在 IE11 的文本框中键入“M-A-T-T”的相同示例。

莫名其妙地,第二个请求需要将近 2 秒才能完成,这是在第四个也是最后一个请求完成之后。这会导致在用户期待“MATT”请求的结果(当前在他们的文本框中)时显示“MA”请求的结果。

如何在 Angular 中处理这个问题?提前致谢。

更新 根据frosty 的回复,我实现了以下(除了弹跳)效果很好:

var cancelDeferred;

var getUsers = function (criteria) {
    if (cancelDeferred) {
        cancelDeferred.resolve();
    }
    cancelDeferred = $q.defer();
    return $http.get(url, { timeout: cancelDeferred.promise }).then(function (response) {
        cancelDeferred = undefined;
        return response.data;
    });
};

实际上,主要的挑战是在调用此方法时处理错误。超时会返回错误,就像 500 会返回错误一样。我想忽略超时并处理实际错误。这是我的解决方案:

function onError(data, status) {
    if (data.data !== null && data.status !== 0) {
        //handle error
    }
}

现在我将尝试找出是否有一种方法可以在全局范围内实现此承诺超时,而不必更改大量 $http.get() 调用...

【问题讨论】:

标签: javascript angularjs angular-http


【解决方案1】:

在 $http 的文档中,它谈到了一个配置对象,您可以将其作为第二个参数传递给 $http.get 调用,如下所示:

$http.get(url, config);

在该配置中,它讨论了您可以设置的“超时”属性。如果你将该属性设置为 Promise,那么如果你解决了这个 Promise,它将中止请求。查看文档以获取那里的描述。

即使您使用去抖动,您也将希望使用此“超时”来中止请求。

https://docs.angularjs.org/api/ng/service/$http

所以你会做这样的事情:

var cancelDeferred;
function makeRequest(){
    if(cancelDeferred) cancelDeferred.resolve(); //when this gets resolved, the previous request will abort. 
    cancelDeferred = $q.defer();
    return $http.get(url,{timeout:cancelDeferred.promise})
        .then(function(res){
            cancelDeferred = undefined;
            return res;
        });
}

因此,您将一个承诺传递给 .get 请求,在配置对象内部作为“超时”属性。如果您在响应返回之前解决此延迟,它将中止请求。

【讨论】:

  • 谢谢!我了解反弹的作用,但你能解释一下这个超时对 $http 请求的作用吗?我似乎无法从文档中完全理解它。
猜你喜欢
  • 2017-01-29
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
  • 2011-01-12
  • 2017-10-05
  • 1970-01-01
  • 1970-01-01
  • 2020-08-04
相关资源
最近更新 更多