递归异步函数

时间:2016-04-21 13:46:16

标签: javascript angularjs rest asynchronous recursion

我对我遇到的问题有疑问。我使用 AngularJS 作为我的框架,无法访问 jQuery Lodash

问题

我有一个名为“刷新”的功能。该函数通过angular $ http进行异步调用,以从服务器获取新数据。从我指定的日期开始,服务器只向我提供25个新的更新。因此,要获取所有新消息,我需要调用服务器(并在每次获取数据时更新“updateDate”),直到它告诉我它没有更多消息(空数组)。

代码示例

$scope.refresh = function () {
    var date = new Date();

    $http({
        method: 'GET',
        url: 'http://path.to.my.server',
        timeout: 6000
    }).then(function (success) {  
        date = success.date[0].date; //0 is always the newest message                     
        callback(success.data);       
        //Do some stuff with the data
    }, function (error) {
        console.error("Could not retrieve new messages: \n", error.data);
        errcallback(error);
    });

}

我尝试了什么

我试图在一个单独的函数中设置请求,并像使用普通的同步函数一样调用它。

我已经尝试了一个while循环并在完成收集时设置了一个布尔值。唯一的问题是while循环不会等待调用结束(否则它不会是异步)并且会产生相当令人印象深刻的循环(不是无限的,但足以让我的程序崩溃)。

我在想一个for循环,但我不知道我应该做多少迭代。它可以是1但也可以是5或更多。

我知道递归函数是如何工作的,但我不知道应该如何使用异步递归函数。欢迎任何建议或解决方案。 (如果有人知道其他解决方案,我不必递归)

2 个答案:

答案 0 :(得分:3)

使异步函数递归是没有什么特别之处的,你不必担心堆栈不足。

只需将你的ajax调用隔离到一个函数中,并让该函数调用自己,直到它有完整的数据图片:

$scope.refresh = function () {
    var date = new Date();
    var results = [];

    gather();

    function gather() {
        $http({
            method: 'GET',
            url: 'http://path.to.my.server',
            timeout: 6000
            // presumably using `date` here?
        }).then(function(success) {
            // This seems to assume you'll always have at least
            // one row, which doesn't seem to match with your description
            date = success.data[0].date; //0 is always the newest message                     
            if (thereAreNewResults) {
                results.push.apply(results, success.data);
                gather();
            } else {
                // We're done
                callback(results);       
            }
        }, function (error) {
            console.error("Could not retrieve new messages: \n", error.data);
            errcallback(error);
        });
    }
};

这并不意味着完整而完美,但它应该让你朝着正确的方向前进。

请注意我的if (thereAreNewResults)。我原以为if (success.data.length),但你问题中的代码似乎表明总是至少有一行,所以请适当调整。

答案 1 :(得分:0)

我将创建一个获取数据的递归函数:

$scope.refresh = function () {

    $scope.allDatas = [];

    var getData = function(date){   
        $http({
            method: 'GET',
            url: 'http://path.to.my.server'+/ date , // should format date her
            timeout: 6000
        }).then(function (success) {  
            date = success.date[0].date; //0 is always the newest message                
            //Do some stuff with the data; all the datas will be available in $scope.allDatas
            $scope.allDatas = $scope.allDatas.concat(success.data);     
            // call again ? 
            if( /* decide when you stop getting data */ ){
                getData(date);
            }
        }, function (error) {
            console.error("Could not retrieve new messages: \n", error.data);
            errcallback(error);
        });
    }
    var date = new Date();
    // launch the function
    getData(date);  
}