递归调用异步 API 调用
Posted
技术标签:
【中文标题】递归调用异步 API 调用【英文标题】:Recursively calling an asynchronous API call 【发布时间】:2018-01-30 12:27:42 【问题描述】:我正在尝试从每次调用仅返回 1000 个项目的 API 获取数据,并且我想递归地执行此操作,直到获得所有数据。
我不知道总共有多少项目,所以每次打电话后我都要检查一下
如果调用是同步的,我会使用这样的:
function fetch(all, start)
const newData = getData(start, 1000);
all = all.concat(newData);
return (newData.length === 1000) ? fetch(all, all.length) : all;
但是,这里的getData()
调用是异步的。使用Promise.all()
不起作用,因为我事先不知道需要多少调用,所以我无法准备调用数组。
我觉得我可以用生成器或async
/await
解决这个问题,但我不知道怎么做。谁能指出我正确的方向?
以防万一,我使用的是 Angular 4。
【问题讨论】:
【参考方案1】:您可以使用async/await
实现此功能,无需递归:
let fetch = async ()
try
let start = 0;
let all = [];
let newData;
do
newData = await getData(start, 1000);
start += newData.length;
all = all.concat(newData);
while (newData.length > 0);
return all;
catch (err)
console.log(err);
【讨论】:
你的解决方案和@estus 的一样好用,但他的只是更干净一点。不过感谢您的回答,我没有意识到这会如此简单。 小心递归函数,如何处理异步函数getData
中抛出的错误也是个问题。
谢谢,我会记住的。我倾向于递归,因为它使代码更具功能性(更少的状态变量),但我同意它确实带来了处理错误的挑战。【参考方案2】:
这取决于您的情况如何完成。考虑到 getData
返回一个承诺,它是:
async function fetch(all, start)
const newData = await getData(start, 1000);
all = all.concat(newData);
return (newData.length === 1000) ? await fetch(all, all.length) : all;
【讨论】:
太棒了,就这么简单。谢谢! 不客气。是的,这就是 async/await 很棒的原因。以上是关于递归调用异步 API 调用的主要内容,如果未能解决你的问题,请参考以下文章
Discord.js - 尝试等待异步进程并允许递归调用包装器