【问题标题】:Recursively calling an asynchronous API call递归调用异步 API 调用
【发布时间】: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。

【问题讨论】:

    标签: javascript angular recursion promise ecmascript-2017


    【解决方案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 很棒的原因。
    猜你喜欢
    • 2017-10-28
    • 2021-05-12
    • 2016-09-21
    • 2014-12-18
    • 2015-08-04
    • 2015-08-27
    • 1970-01-01
    • 2016-04-28
    • 2017-05-13
    相关资源
    最近更新 更多