javascript – AngularJS中的承诺顺序

题:

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

我有一个长时间运行的计算,我通过$http请求结果.某些操作或事件要求我在解决初始承诺之前重新开始计算(从而发送新的$http请求).因此,我想我不能使用像这样的简单实现

$http.post().then(function(){
    //apply data to view
})

因为我无法确保响应按照我发送请求的顺序返回 – 毕竟我想在所有承诺得到妥善解决时显示最新计算的结果.

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

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

思考:

使用$http时,我可以访问响应上的config-object,使用一些时间戳或其他标识符来手动排序传入的响应.但是我希望我能以某种方式告诉角度取消过时的承诺,因此在解决时不会运行.then()函数.

如果没有手动实现$q-promises而不是$http,这不起作用.

也许只是拒绝承诺就是要走的路?但在这两种情况下,它可能需要永远,直到最终在生成下一个请求之前解决了一个promise(在此期间导致一个空视图).

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

最佳答案
我通过生成一个requestId来实现,并在promise的then()函数中检查响应是否来自最近的requestId.

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

就像是:

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的这个概念也可以应用于防止重复请求.例如,在我的数据服务的load(模块,id)方法中,我做了一个这样的过程:

>根据URL参数生成requestId.
>检入requestId的请求哈希表

>如果未找到requestId:在哈希表中生成新请求和存储承诺
>如果找到requestId:只需从哈希表中返回promise

>请求完成后,从哈希表中删除requestId的条目.

转载注明原文:javascript – AngularJS中的承诺顺序 - 代码日志