AngularのHTTPインターセプターで同時HTTPリクエスト数を制限する
AngularのHTTPインターセプターと非同期ロック処理を組み合わせると、とても無駄な感じもしますが、AJAXリクエストの同時リクエスト数を制限することができます。ブラウザが同時に6本までしか送らないのでぶっちゃけ無駄な気もしますが、有用なこともあるでしょう。。。
非同期ロックライブラリのインストール
今回は await-semaphore
を使用します。 npm i -P await-semaphore
を実行してインストールします。
HTTPインターセプターの実装
非同期ロックを実行しつつ次の処理を実行するとこんな感じになります。
Semaphore
のコンストラクターに渡す数値で同時実行数が制限されます。キモは finalize
オペレーターを使用してHTTPリクエスト終了時にセマフォを解放することです。
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Semaphore } from 'await-semaphore'; import { from, Observable } from 'rxjs'; import { finalize, switchMap } from 'rxjs/operators'; /** * HTTPリクエストの同時処理数を制限するHTTPインターセプター */ @Injectable() export class SequentialRequestHttpInterceptor implements HttpInterceptor { private readonly semaphore = new Semaphore(1); intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return from(this.acquire()).pipe( switchMap(release => next.handle(req).pipe(finalize(() => release()))), ); } private async acquire() { return await this.semaphore.acquire(); } }