如何在满足条件之前“循环”Axios GET 调用?

Posted

技术标签:

【中文标题】如何在满足条件之前“循环”Axios GET 调用?【英文标题】:How can I "while loop" an Axios GET call till a condition is met? 【发布时间】:2017-12-24 02:23:49 【问题描述】:

我有一个 API,它返回一个留言板线程的回复列表(每次调用限制 5 个回复)。我想要做的是在响应中寻找特定的回复 uuid。如果未找到,请再次调用 AXios GET 以获取接下来的 5 个回复。

我想继续这个循环,直到调用 UUID 或 AXIOS GET 调用返回但没有结果。

示例 API 请求:

http://localhost:8080/api/v2/replies?type=thread&key=e96c7431-a001-4cf2-9998-4e177cde0ec3

示例 API 响应:

"status": "success",
"data": [
    
        "uuid": "0a6bc471-b12e-45fc-bc4b-323914b99cfa",
        "body": "This is a test 16.",
        "created_at": "2017-07-16T23:44:21+00:00"
    ,
    
        "uuid": "0a2d2061-0642-47eb-a0f2-ca6ce5e2ea03",
        "body": "This is a test 15.",
        "created_at": "2017-07-16T23:44:16+00:00"
    ,
    
        "uuid": "32eaa855-18b1-487c-b1e7-52965d59196b",
        "body": "This is a test 14.",
        "created_at": "2017-07-16T23:44:12+00:00"
    ,
    
        "uuid": "3476bc69-3078-4693-9681-08dcf46ca438",
        "body": "This is a test 13.",
        "created_at": "2017-07-16T23:43:26+00:00"
    ,
    
        "uuid": "a3175007-4be0-47d3-87d0-ecead1b65e3a",
        "body": "This is a test 12.",
        "created_at": "2017-07-16T23:43:21+00:00"
    
],
"meta": 
    "limit": 5,
    "offset": 0,
    "next_offset": 5,
    "previous_offset": null,
    "next_page": "http://localhost:8080/api/v2/replies?_limit=5&_offset=5",
    "previous_page": null

循环将在 meta > next_page url 上调用 AXIOS GET,直到在结果中找到 uuid 或 meta > next_page 为空(意味着不再回复)。

【问题讨论】:

你试过什么?到目前为止,您似乎还没有做出任何努力。 一些上下文?这是在 Vue 方法中吗? @DavidL 我已经玩了一段时间了。我尝试过传统的 while 循环,由于 AXIOS 的承诺,它不起作用。我也尝试过构建一个 Promise while 循环 (gist.github.com/tangzhen/7b9434df8beac308fd3e),但这也行不通。 @BertEvans 它位于 Vue.js 2 组件的“已创建”挂钩内。 看看这个,while loop w/ promises 【参考方案1】:

你应该搜索的不是while loop,而是叫Recursion:

var counter = 10;
while(counter > 0) 
    console.log(counter--);

递归

var countdown = function(value) 
    if (value > 0) 
        console.log(value);
        return countdown(value - 1);
     else 
        return value;
    
;
countdown(10);

这意味着函数会根据输出的特定标准不断调用自己。这样,您可以创建一个处理响应的函数,并在该值不适合您时再次调用自身(半代码):

function get() 
    axios.get('url').then(function(response) 
        if (response.does.not.fit.yours.needs) 
            get();
         else 
            // all done, ready to go!
        
    );


get();

如果你想用 Promise 链接它,那么你应该花一些时间自己弄清楚,每次只返回一个 Promise ;)

【讨论】:

这最终不会导致堆栈溢出吗? 这就是为什么它总是有一个if 条件,所以如果满足要求,它会再次调用相同的函数only。在第一种情况下是if (value > 0),在第二种情况下是if (response.does.not.fit.your.needs),这基本上是你喜欢的任何东西:) 哦,抱歉,没看到,我专注于我的特殊 while 条件,它不是基于计数器,而是基于长期运行的工作状态。在这种情况下,它仍然可能导致堆栈溢出。我什至没有想到计数器,因为我不知道为什么有人会为计数器使用 while 循环而不是 for。我最终使用了 setInterval 和 clearIntetval,因为我找不到解决这个问题的递归解决方案。考虑到问题的标题,我仍然认为应该在答案中解决这个问题 我想我已经以适当的方式回答了用户的问题,并结合了他的解释和他自己的例子。所以这两种情况(有或没有while)都包括在内。随意使用它们中的任何一个;)不完全确定为什么答案不能满足您的需求 我似乎不明白你实际上在吹嘘什么 :) 如果你仍然希望在 while 循环中使用 axios 响应,那么我认为我们应该立即结束这个讨论;) 如果您有更好的答案,请发布。这样的谈话对任何人都没有帮助,甚至会让人更加困惑。【参考方案2】:

如果您使用支持异步/等待的东西进行预编译,这很简单。下面只是一个例子。在您的情况下,您将检查您的 guid 或空响应。

new Vue(
  el:"#app",
  methods:
    async getStuff()
      let count = 0;
      while (count < 5)
        let data = await axios.get("https://httpbin.org/get")
        console.log(data)
        count++
      
    
  ,
  mounted()
    this.getStuff()
  
)

或者,根据您对我的评论的回复,

new Vue(
  el:"#app",
  async created()
      let count = 0;
      while (count < 5)
        let data = await axios.get("https://httpbin.org/get")
        // check here for your guid/empty response
        console.log(data)
        count++
      
  
)

Working example(至少在最新的 Chrome 中)。

【讨论】:

你不应该在浏览器中使用asyncawait,因为它们会生成大量的代码,而且仍然很慢:) @AndreyPopov 我在第一行提到了预编译。 我看到你提到了预编译,但它仍然不适合网络浏览器(不幸的是!):( @AndreyPopov 将同意不同意。任何性能问题都会被它进行网络调用和简单明了的事实所淹没。

以上是关于如何在满足条件之前“循环”Axios GET 调用?的主要内容,如果未能解决你的问题,请参考以下文章

for 循环中的 axios.get().then()

在 axios 响应做出反应后,如何有条件地重定向到页面?

为啥while循环有时会在满足退出条件之前退出?

vuejs 应用程序中异步 axios 调用的多个响应的竞争条件

尝试循环 API 调用直到满足条件

在循环内进行重复的ajax调用,直到满足条件