【问题标题】:Angular Timeout in for Loopfor循环中的角度超时
【发布时间】:2021-01-02 23:37:33
【问题描述】:

目前我尝试在 Angular 中构建数据导入。一切正常,但我的后端只允许大约 70 个请求。所以它会出错。我的想法是通过发布请求在 Angular for Loop 中设置超时。这是处理这个问题的正确方法吗?如果是,该怎么做?找不到任何解决方案。 这是我目前的要求:

for( let x of this.data ){
    this.http.post(url,x,{ headers: (reqHeader)}).toPromise().then((data: any) => { console.warn(this.data) })
}

【问题讨论】:

标签: angular rest


【解决方案1】:

也许rate limiting 就是您要找的东西?

... 然后我们将它与 bufferTime 和 concatMap 链接起来。连接地图 运算符是我们强制延迟 1000 毫秒的地方:

const startTime = (new Date()).getTime();

const source = Observable.range(1, 25)
  .concatMap(val => Observable.of(val).delay(75));

source.bufferTime(1000, null, 5)
  .concatMap(buffer => Observable.of(buffer).delay(1000))
  .timestamp()
  .map(obj => {
    obj.timestamp = obj.timestamp - startTime;
    return obj;
  })
  .subscribe(obj => console.log(obj));

【讨论】:

  • 非常感谢,看来它s what I need, but cant 弄清楚如何使用我的代码。必须把它放入for循环吗?如何导入 Observable.range?显示我不存在。非常感谢。
【解决方案2】:

不确定您所说的后端仅允许大约 70 个请求。但是如果你想控制一次并行请求的数量,你可以使用 RxJS 的 frombufferCountforkJoin 函数和 concatMap 运算符。

  1. 尽量避免toPromise()。切换回熟悉的 Promise 范式是一种更简单的方法,但它在 RxJS 7 中为 deprecated,将在 RxJS 8 中消失。而是尝试订阅 observables。

  2. 对于受控的并行请求,请尝试以下操作

const reqs = this.data.map(item => this.http.post(url, item, { headers: (reqHeader) }))

from(reqs).pipe(
  bufferCount(6),      // <-- adjust number of parallel requests here
  concatMap(buffer => forkJoin(buffer))
).subscribe(
  res => console.warn(res),
  err => console.log(err),
  () => console.log('complete')
);

更新:延迟每个请求

您可以放弃bufferCount,而是单独切换到每个请求并使用显式延迟。试试下面的

from(this.data).pipe(
  concatMap(item => this.http.post(url, item, { headers: (reqHeader) }).pipe(
    delay(3000)     // <-- wait 3 seconds b/n each request
  ))
).subscribe(
  res => { },
  err => { }
);

更新:计算排放量

您可以引入一个变量(例如count)并使用map 运算符来返回计数和响应。

试试下面的

someFunc() {
  let count = 0;

  from(this.data).pipe(
    concatMap(item => this.http.post(url, item, { headers: (reqHeader) }).pipe(
      map(res => {
        count++;
        return {
          count: count,
          response: res
        }
      }),
      delay(3000)     // <-- wait 3 seconds b/n each request
    ))
  ).subscribe(
    res => {
      console.log(res.count);        // <-- the count of the emission
      console.log(res.response);     // <-- the response from `this.http.post()`
    },
    err => { }
  );
}

【讨论】:

  • 我将 bufferCount(1) 接缝转为运行良好,但在 arround 60 个请求之后:标头:{…},状态:429,状态文本:“请求过多”
  • 您的回复是否有Retry-After 标头?等待时间是多久?
  • 等待时间大约是几秒钟。有没有办法在里面放延迟?
  • @SaschaK:我已经使用delay 运算符更新了答案,使每个请求都有一个明确的等待时间。请检查它是否适合您。
猜你喜欢
  • 2011-11-19
  • 2022-10-24
  • 2015-09-10
  • 2021-11-03
  • 1970-01-01
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多