【问题标题】:AngularJS - How to cancel a promise? [duplicate]AngularJS - 如何取消承诺? [复制]
【发布时间】:2016-02-04 01:25:29
【问题描述】:

假设我有一个输入文本字段(更像 Google 搜索字段),更改后会触发请求并显示一些结果。

例如,

让我们在输入中输入Dog

typed D -> Calls ctrl.search('D') -> Makes a request -> Changes model when success
typed DO -> Calls ctrl.search('DO') -> Makes a request -> Changes model when success
typed DOG -> Calls ctrl.search('DOG') -> Makes a request -> Changes model when success.

现在,假设DO 请求比DOG 响应晚。即使我输入了DOG,我的模型最终也会得到DO 的结果。

为此,如果我继续输入字符,我需要一种方法来取消或中止当前正在进行的请求。这样一来,我的模型只会被最终请求更改。

我的输入如下所示:

<input type="text" class="form-control" data-ng-model="query" data-ng-change="ctrl.search(query)" placeholder="Search" />

这是我的searchCtrl.js

var search;
var language;
var _this;

var SearchCtrl = function (searchService, lang)
{
     search = searchService;
     langauge = lang;
     _this = this;
}

SearchCtrl.prototype.search = function (text)
{
    var promise = search.language(language)
                  .facet('characters')
                  .highlight('quotes')
                  .query(text);

    promise.then(function (response) {
         if(!response) return;
         _this.total = response.total;
         _this.count = response.found;
         _this.result = response.data;
    });
}

【问题讨论】:

  • 我们不能取消promise..要么我们需要rejectresolve 它来完成它..
  • 1) 在您的文本框中使用 debounce,您可以使用 ng-model-options 2) 您可以为 http 选项的 timeout 属性提供一个承诺,您可以取消它(通过拒绝该延迟对象),但该请求仍将由服务器处理,它只会在客户端级别被拒绝。
  • 解决这个问题的最好办法是在输入出现短暂暂停之前先不发送请求。如果服务器已经收到请求,取消请求不会停止处理它。查看docs.angularjs.org/api/ng/directive/ngModelOptions 特别是去抖动选项。

标签: javascript angularjs promise deferred


【解决方案1】:

通常对于这种情况人们使用ng-model-options={debounce: 100}

https://docs.angularjs.org/api/ng/directive/ngModelOptions

无论如何你都可以拒绝承诺。

【讨论】:

  • 这成功了!非常感谢!这是否像发送每个请求之前的延迟?
  • 是的,它可以帮助你;)不客气。
  • @MatiasCicero 它基本上是一个超时,每次值更改时都会重置。因此,如果值在 100 毫秒内停止变化,则计时器结束并发送请求。
  • 这仍然不能解决您原来的问题...如果延迟的“DO”返回晚于更延迟的“DOG”,它仍将使用“DO”结果。您所做的只是将调用保存到服务器。
【解决方案2】:

我认为您想在这种情况下使用debounce 技术?

见:

【讨论】:

  • 谢谢! 'blur': 0 是做什么的?
  • 我从文档中复制了它,在您的情况下可能不需要,离开现场时它不会有去抖延迟(因为它是 0),您可以根据每个事件类型(如果需要)
【解决方案3】:

像这样:$q.reject(response);

虽然从技术上讲,我相信上述评论者是正确的,但您实际上是在拒绝承诺而不是真正取消它。

【讨论】:

  • 那不会也拒绝我的最终请求吗?如果用户仍在输入,那么仅中止请求的逻辑是什么?
  • 我在完全理解您的代码示例之前就回答了,上面的 debounce 答案是满足您需求的更好方法。
猜你喜欢
  • 2017-05-24
  • 2015-07-25
  • 2013-12-08
  • 1970-01-01
  • 2017-09-21
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
  • 2018-12-10
相关资源
最近更新 更多