【问题标题】:Recursively fetching data with axios and chaining the result使用 axios 递归获取数据并链接结果
【发布时间】:2018-09-25 03:52:26
【问题描述】:

我有一个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))

最好的方法是什么?

【问题讨论】:

  • 不确定最佳方式,但我会选择async/awaitwhile 循环,直到它得到404 响应。
  • 什么是getLeadData
  • 我认为函数getLeadData也应该返回promise?
  • 我猜你从 getData 函数返回 promise p,但是因为你希望从 catch 得到结果,你是否也尝试返回这个?:return Promise.resolve(returnArray);跨度>
  • 抱歉,忘记重命名函数,getLeadData 等于getData

标签: javascript promise axios


【解决方案1】:

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 指出的那样,您还需要在 catch 处理程序中返回 returnArray,而不是:

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;
  }
)};

【讨论】:

  • 还有来自catch处理程序的returnreturnArray
【解决方案2】:

我相信连接的顺序取决于计数,因此您必须一个接一个地对承诺进行排序。

您可以通过增加cnt 参数并在sp 函数的rs 参数中累积结果来进行递归连接,直到最终一个promise 拒绝。一旦被拒绝,由于之前的所有解析都已经连接在 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 解决后才注册。所以另一种方法是在子数组中批量处理一组承诺作业,并将这些块与Promise.all() 一起使用。也可以以类似的递归方式实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-13
    • 2017-02-16
    • 1970-01-01
    相关资源
    最近更新 更多