我有一个模式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))
这样做的最佳方式是什么?
答案 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()
一起使用。这也可以以类似的递归方式实现。