2016-04-21 5 views
1

У меня есть вопрос о проблеме, с которой я сталкиваюсь. Я использую AngularJS как мои рамки и не имеют доступа к jQuery или Lodash.Рекурсивная функция Async

Проблема

У меня есть функция под названием "обновить". Эта функция выполняет асинхронный вызов через угловой $ 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); 
    }); 

}


То, что я пытался

Я пытался получить установить запрос в виде отдельной функции и совершать звонки на него как вы бы сделали с нормальной функцией a-sync.

Я также пробовал цикл while и устанавливал логическое значение, когда я закончил со сбором. Единственная проблема заключается в том, что цикл while не ждет завершения вызова (иначе это не будет async) и делает довольно впечатляющий цикл (еще не бесконечный, но достаточно, чтобы разбивать мою программу).

Я думал о цикле for, но я не знаю, сколько итераций я должен сделать. Это может быть 1, но также может быть 5 или более.

Я знаю, как работают рекурсивные функции, но я не знаю, как использовать рекурсивную функцию async. Любые советы или решения приветствуются. (Мне не обязательно быть рекурсивным, если кто-нибудь знает другое решение)

+0

как вы послали дату в WebService? – AlainIb

+1

Итак, вы уже пытались выполнить '$ scope.refresh()' в обратном вызове '.then()'? –

ответ

4

Нет ничего особенного в том, чтобы сделать рекурсивные функции async, вам просто не нужно беспокоиться о том, чтобы закончиться из стека.

Просто изолировать АЯКС вызов в функцию, и есть, что вызов функции непосредственно, пока он не имеет полное представление о данных:

$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); 
} 
Смежные вопросы