【问题标题】:How to make api call with parms from an array continously如何使用数组中的参数连续进行 api 调用
【发布时间】:2021-07-29 20:43:50
【问题描述】:

我有一个包含一些值的数组,这些值应该作为参数传递给 api 调用。 我想用 api 调用的结果更新数据。我想用数组的每个值每 1 秒调用一次 api。

示例:

const people = [1, 2, 3, 4, 5];

people.forEach((person, index) => {
  setTimeout(() => {
    fetch(`https://swapi.dev/api/people/${person}/`)
      .then(res => res.json())
      .then(data => {
        // do stuff, eg : update UI
        console.log(data.name);
      })
  }, index * 1000);

});

由于我想继续调用 api 并不断更新数据或 UI,因此将 forEach() 包装在无限循环中是个好主意,如下所示:

 while(true) {
          people.forEach((person, index) => {
              setTimeout(() => {
                  fetch(`https://swapi.dev/api/people/${person}/`)
                    .then(res => res.json())
                    .then(data => {
                        // do stuff, eg : update UI
                        console.log(data.name) ;
                      })
                    }, index * 1000);

              }) ;
            } ;

如果这是一个坏主意,请说明原因并建议其他方法来做正确的事。 提前致谢。

更多信息:- 我要使用的 api 的速率限制为每 5 秒 100 次 api 调用,所以我必须每 3 秒调用一次以保持实时而不达到限制。

每个数组元素都是不同的端点,因此需要对其进行完全迭代以尽可能保持数据的实时性。

此脚本应该 24/7 运行以更新数据

starwars api 仅用作示例,因为这是我想到的第一个。

【问题讨论】:

  • 这是一个非常糟糕的主意,因为 while 循环迭代不会等待超时。您将以这种方式每秒安排数千次超时。您可以使用外部间隔,使循环每 5 秒运行一次(快速但不好的修复),或使用交错间隔。
  • 你能解释一下吗?
  • 我建议至少做一个setInterval() 而不是一段时间。您的 api 可以更改为接受任意数量的人,而不是一次只接受一个人吗?他们的数据多久更改一次?
  • 我的意思是这样的:jsfiddle.net/zj19g6pk
  • 你看我的小提琴了吗?我将调用移至一个函数,并在初始循环中专门调用它以防止延迟。

标签: javascript infinite-loop


【解决方案1】:

您可以做的事情是使用setInterval()people 数组长度的间隔时间来获得所需的行为。

const people = [1, 2, 3, 4, 5];

setInterval(() => {
  people.forEach((person, index) => {
    setTimeout(() => {
      fetch(`https://swapi.dev/api/people/${person}/`)
        .then(res => res.json())
        .then(data => {
          // do stuff, eg : update UI
          console.log(data.name);
        })
     }, index * 1000);
  });
}, people.length * 1000);

但是现在你对你的服务器非常健谈,我建议你做一个批量获取,你可以一次获取所有用户而不是单独获取(并且你可以更频繁地调用以保持 ui 最多日期尽可能)。我假设这是你的 api,如果你愿意,你可以添加一个新函数。

const people = [1, 2, 3, 4, 5];

setInterval(() => {
  people.forEach((person, index) => {
    fetch(`https://swapi.dev/api/people/getList/`, {
         method: 'GET',
         body: JSON.stringify(people)
      })
      .then(res => res.json())
      .then(data => {
        // do stuff, eg : update UI
        console.log(data.name);
      })
  });
}, 3000);

【讨论】:

  • api返回的数据也是实时更新的,所以我想我得一直打电话来获取更新的数据
  • @me.nkr 这就是setInterval 在这里所做的,而不是setTimeout
  • @me.nkr Chris 是对的,setInterval() 函数基本上是一个无限循环,您可以为每次迭代设置延迟
  • 那么间隔应该是多少?它是否比使用 while(true) 的无限循环更好?
  • @me.nkr 间隔为people.length * 1000。因此,如果您有 10 个人,它将等待 10 秒钟,然后再呼叫第一个人。如果您有 5 个人,它将等待 5 秒钟,然后再呼叫第一个人。它好多了,因为while(true) 运行得尽可能快。它不会等待 settimeout 做它的事情
【解决方案2】:

这最初是由@Chris G 提供的

这个工作就像一个魅力

const people = [1, 2, 3, 4, 5];

function apiCall(person) {
      fetch(`https://swapi.dev/api/people/${person}/`)
        .then(res => res.json())
        .then(data => {
          // do stuff, eg : update UI
          console.log(data.name);
        });
        
}

people.forEach((person, index) => {

  setTimeout(() => {
        apiCall(person);
    
    setInterval(() => {
            apiCall(person);
    }, people.length * 1000);
    
  }, index * 1000);

});

只是因为我花了一些时间来了解上面的代码是如何工作的,所以我将在下面提供一些细节:

forEach 循环执行并退出,但在执行时触发了 setTimeouts,当 setTimeouts 运行时触发了 setIntervals。所有这些实际上都在 forEach 循环之外运行,但由于关闭而能够访问变量

【讨论】:

    猜你喜欢
    • 2018-08-18
    • 1970-01-01
    • 2013-08-31
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 2017-12-20
    • 2017-06-19
    相关资源
    最近更新 更多