使用axios递归获取数据并链接结果

时间:2018-04-15 08:12:38

标签: javascript promise axios

我有一个模式http://www.data.com/1的网址,其中最后的1可以运行直到未预定义的数字。它返回一个数组。我需要连接我所有的数组。

我的策略是递归执行get-request,直到我收到404错误,然后返回结果。

var returnArray = [];

function getData(count){
let p = axios.get(`http://www.data.com/${count}`).then(function(response){
  returnArray = returnArray.concat(response.data);
  return getData(count +1);
}
).catch(function() {
    Promise.resolve(returnArray);
}
)};

但是,当我实现此功能时,我的结果是未定义的。

getData(1).then((response) => console.log(response))

这样做的最佳方式是什么?

2 个答案:

答案 0 :(得分:3)

getData内,您没有返回承诺,因此函数会立即以未定义的值退出。 所以,而不是:

let p = axios.get(`http://www.data.com/${count}`).then(function(response){

使用:

return axios.get(`http://www.data.com/${count}`).then(function(response){
编辑:正如Bergi指出的那样,你还需要在returnArray处理程序中返回catch,而不是:

Promise.resolve(returnArray);

使用:

return returnArray;

这是完整的代码:

var returnArray = [];

function getData(count){
  return axios.get(`http://www.data.com/${count}`).then(function(response){
    returnArray = returnArray.concat(response.data);
    return getData(count +1);
  }
  ).catch(function() {
    return returnArray;
  }
)};

答案 1 :(得分:0)

我认为连续的顺序取决于计数,所以你必须一个接一个地对承诺进行排序。

您可以通过增加cnt参数并在rs函数的sp参数中累积结果来进行递归连接,直到最终承诺拒绝为止。一旦被拒绝,由于之前的所有决议都已在rs参数中连接,只需将其返回catch阶段即可。

在下面的代码ps中,数组类似于API,而ps[cnt]类似于对API的调用;

axios.get(`http://www.data.com/${cnt}`);

var ps = [new Promise((v,x) => setTimeout(v,Math.random()*1000,[0,1,2])),
          new Promise((v,x) => setTimeout(v,Math.random()*1000,[3,4,5])),
          new Promise((v,x) => setTimeout(v,Math.random()*1000,[6,7,8])),
          new Promise((v,x) => setTimeout(x,1000,null))],
    sp = (cnt = 0, rs = []) => ps[cnt].then(vs => sp(++cnt, rs.concat(vs)))
                                      .catch(e => rs);

sp().then(console.log);

这种排序方法当然需要时间,因为每个其他承诺只有在前一个承诺得到解决后才能注册。所以另一种方法可以是在子数组中批处理一组promise工作,并将这些块与Promise.all()一起使用。这也可以以类似的递归方式实现。