javascript - AngularJS 中的 promise 顺序

标签 javascript angularjs promise angular-promise cancellation

问题:

是否有一种“简单”的方法来取消 AngularJS 中的 ($q-/$http-)promise 或确定解决 promise 的顺序?

示例

我有一个长时间运行的计算,我通过 $http 请求结果。在初始 promise 得到解决之前,某些操作或事件要求我重新启动计算(并因此发送新的 $http 请求)。因此我想我不能使用像

这样的简单实现
$http.post().then(function(){
    //apply data to view
})

因为我无法确保响应按照我发送请求的顺序返回 - 毕竟我想在所有 promise 都得到正确解决时显示最新计算的结果。

但是我想避免等待第一个响应,直到我发送这样的新请求:

const timeExpensiveCalculation = function(){
    return $http.post().then(function(response){
        if (isNewCalculationChained) {return timeExpensiveCalculation();}            
        else {return response.data;}
    })
}

想法:

当使用 $http 时,我可以访问响应上的配置对象以使用一些时间戳或其他标识符来手动排序传入的响应。然而,我希望我能以某种方式告诉 Angular 取消一个过时的 promise ,从而在它得到解决时不运行 .then() 函数。

如果没有手动实现 $q-promises 而不是 $http,这将无法工作。

也许直接拒绝 promise 才是正确的选择?但在这两种情况下,在生成下一个请求之前可能需要很长时间才能最终解决 promise (同时导致空 View )。

是否有一些我遗漏的 Angular API 函数,或者是否有强大的设计模式或带有 promise 链或 $q.all 的“技巧”来处理返回“相同”数据的多个 promise ?

最佳答案

我通过生成一个 requestId 来做到这一点,并在 promise 的 then() 函数中检查响应是否来自最近的 requestId.

虽然这种方法实际上并没有取消之前的 promise ,但它确实提供了一种快速简便的方法来确保您正在处理最新的请求响应。

类似于:

var activeRequest;
function doRequest(params){
    // requestId is the id for the request being made in this function call
    var requestId = angular.toJson(params); // I usually md5 hash this

    // activeRequest will always be the last requestId sent out
    activeRequest = requestId;

    $http.get('/api/something', {data: params})
        .then(function(res){
            if(activeRequest == requestId){
                // this is the response for last request

                // activeRequest is now handled, so clear it out
                activeRequest = undefined;
            }
            else {
                // response from previous request (typically gets ignored)
            }
        });
}

编辑: 在旁注中,我想补充一点,这种跟踪 requestId's 的概念也可以应用于防止重复请求。例如,在我的 Data 服务的 load(module, id) 方法中,我做了一个像这样的小过程:

  1. 根据 URL + 参数生成 requestId
  2. 检查 requestId

    的请求哈希表
    • 如果未找到requestId:生成新请求并将 promise 存储在哈希表中
    • 如果找到requestId:简单地从哈希表返回 promise
  3. 请求完成后,从哈希表中删除 requestId 的条目。

关于javascript - AngularJS 中的 promise 顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38265239/

相关文章:

javascript - Angular 2.0 CLI 项目中 div 元素上的自定义滚动条?

javascript - Angular ng-repeat 只显示最后一个元素。如果只有一个元素,则不显示任何内容

node.js - 将 Promise 与 CouchDB nano 和 forEach 结合使用

javascript - Angular 1 ng-如果不显示div

javascript - 使用 Jsonwebtokens 的 Promises 与 Async

javascript - Mocha/节点 : how to use assert. 拒绝()?

javascript - 面对超过 2000 个项目时,Dynatree 返回错误

javascript - 仅在 Shift-Select 时保持 select2 打开

javascript - Vue.js eslint 解析错误。 : unexpected token

javascript - AngularJS 从 Controller 更改 ng-view 中的 View