首页 > 解决方案 > 按顺序处理请求

问题描述

主要目标是按顺序处理我的请求。我已经输入了扫描仪快速扫描值的输入。但有时服务器返回数据很慢,如果我扫描得很快,服务器就会崩溃并返回 500。我的想法是按顺序处理这个请求。我试图找到一些解决方案,但我没有找到我想要的。我不知道我是否应该使用一些拦截器,或者将其保存在服务或组件中。

我试图在拦截器中找到解决方案,但是我没有发现请求何时完成并且拦截器可以处理下一个请求。我尝试使用 rxjs 运算符,但我不知道如何合并到我的解决方案中。这是我想要在我的解决方案中的示例

from([1, 2, 3, 4])
  .pipe(
    concatMap(param =>
      this.http.get(
        `http://localhost:6013/api/v1/test/buffer?data=${param}`
      )
    )
  )
  .subscribe(res => console.log(res));

from 操作员使我的请求可观察,ConcatMap 按顺序处理它

有我的骨架应用程序

app.component.ts

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FormBuilder, Validators } from '@angular/forms';
import { Subject } from 'rxjs';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  form = this.fb.group({
    input: ['', Validators.required]
  });

  makeRequest$ = new Subject();
  constructor(private http: HttpClient, private fb: FormBuilder) {}

  onSubmit() {
    this.http
      .get(
        `http://localhost:6013/api/v1/test/buffer?data=${
          this.form.controls.input.value
        }`
      )
      .subscribe(res => {
        console.log(res);
      });

    this.form.reset();
  }

  ngOnInit() {}
}

app.interceptor.ts

import { Injectable } from '@angular/core';
import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpEvent
} from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class AppInterceptor implements HttpInterceptor {
  arrayRequest: Array<HttpRequest<any>> = [];

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return next.handle(req);
  }
}

app.components.html

<form [formGroup]="form" (ngSubmit)="onSubmit()">
  <label>
    Data:
    <input type="text" formControlName="input" />
  </label>

  <button type="submit" [disabled]="!form.valid">Submit</button>
</form>

我排除了上面的代码之类的东西。ConcatMap 按顺序处理请求,但我不知道我应该如何处理请求以及我应该如何选择方向。

标签: angulartypescriptrxjs6

解决方案


据我了解您的问题,您需要在提交时按顺序执行 api 请求。在您的情况下,您需要 rxjs Subject 来实现预期的行为。我修改了您的组件,以便您可以查看 ngOnInit 和 onSubmit 函数。

makeRequest$ 现在是可观察的,每次 onSubmit 方法调用都会有新事件到达。您可以使用 concatMap 顺序发送 api 请求,也可以使用延迟运算符在请求完成后暂停一段时间,以免服务器受到太多打击。

还可以查看unsubscribe$ 和 takeUntil(this.unsubscribe$) <- 这些用于在组件被销毁后释放内存,以避免内存泄漏。这是这样做的最佳实践之一。

import { Component, OnInit } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { FormBuilder, Validators } from "@angular/forms";
import { Subject } from "rxjs";
import { concatMap, takeUntil, delay } from "rxjs/operators";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"]
})
export class AppComponent implements OnInit {
  public form = this.fb.group({
    input: ["", Validators.required]
  });

  private makeRequest$ = new Subject();
  private unsubscribe$ = new Subject();

  constructor(private http: HttpClient, private fb: FormBuilder) {}

  ngOnInit() {
    this.makeRequest$
      .pipe(
        delay(500),
        concatMap(item =>
          this.http.get(`http://localhost:6013/api/v1/test/buffer?data=${item}`)
        ),
        takeUntil(this.unsubscribe$)
      )
      .subscribe();
  }

  ngOnDestroy(): void {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }

  public onSubmit() {
    this.makeRequest$.next(this.form.controls.input.value);
    this.form.reset();
  }
}

推荐阅读