执行一组递归HTTP GET调用,并等待它们全部

时间:2017-12-29 12:37:34

标签: javascript jquery

我有一个REST服务,提供一个'Json'对象列表,每个对象可能有一个链接,用于其自己类的另一个资源。从特定的一个开始,我需要全部获取它们,执行递归的http调用。 所以我写道:

var steps = [];
var recursiveLookup = function(processId) {
  return $.ajax({
    url: SERVER_URL + processId,
    success: function (activity) {
      // Activity has a set of json objects called steps
      var rtn = activity.path.map(step => {
        if (step.type != "Node") {
          steps.push(step);
        } else {
          return recursiveLookup(step.subProcessIntanceId);
        }
      }).filter(a => a != undefined);
      return rtn;
    }
  });
}

这会将所有对象正确加载到全局步骤var中。 我需要确定方法已经完成,所以我写道:

var promises = recursiveLookup(processId);
Promise.all(promises).then(function () {
   console.log(steps);
});

但它不起作用,因为'recursiveLookup'返回$ .ajax的承诺,而不是假装用success方法返回的promise集。

此外,是否可以将步骤作为“recursiveLookup”方法的返回值,而不是将其用作全局变量?

2 个答案:

答案 0 :(得分:1)

嵌套递归不在我的confort区域内,但可能会有效:

var recursiveLookup = function(processId,steps=[]) {
  return $.ajax({
    url: SERVER_URL + processId,
  })
  .then(
    function (activity) {
      // Activity has a set of json objects called steps
      steps = steps.concat(
        activity.path.filter(
          step => step.type !== "Node"
        )
      );
      return Promise.all(
        activity.path.filter(
          step => step.type === "Node"
        )
        .map(
          step=>
            recursiveLookup(step.subProcessIntanceId,steps)
        )
      ).then(
        result=>steps.concat(result)
      )
    }
  );
}

对于尾部调用优化工作,函数最后应该调用递归函数,但我认为在promise链中它并不重要。

答案 1 :(得分:-2)

如果您想使用promises,则不应使用success参数。相反,你想要返回一个承诺,然后你想用它将一个承诺的结果转换成不同的东西,甚至是另一个承诺。

function request(page) {    
…
// return the AJAX promise
return $.ajax({
    url: '/echo/json/',
    method: 'POST',
    dataType: 'json',
    data: {
        delay: 1,
        json: JSON.stringify(ret)
    }
 });
}

function requestOddsFrom(page, items) {
return request(page).then(function(data){
    if (data.currentPage > data.totalPage) {
        return items;
    } else {
        var filtered = data.items.filter(function(el){ return el%2 == 1; });
        return requestOddsFrom(data.currentPage + 1, items.concat(filtered));
    }
 });
}

function requestAll(){
return requestOddsFrom(1, []);
}

 requestAll().then(function(items) {
   console.dir(items);
});

了解更多信息jQuery Recursive AJAX Call Promise

How do I return the response from an asynchronous call?