TypeScript - вызов конечной точки API снова и снова, пока мы не получим желаемый результат - рекурсия или l oop? - PullRequest
0 голосов
/ 08 февраля 2020

У меня есть приложение с внешним интерфейсом и приложение с внутренним интерфейсом. Приложение внешнего интерфейса запрашивает у бэкэнда выполнить фоновое задание (например, DELETE /api/v1/object/666), сервер отвечает с HTTP 202 и дает ссылку на задание (например, https://.../api/v1/job/13). Теперь приложение внешнего интерфейса должно периодически вызывать эту конечную точку до завершения задания.

Я реализовал это как рекурсивный вызов, это выглядит так:

  checkAsyncJob(
    jobId: string,
    interval: number = 2048,
    keepTrying: boolean = true,
    onFinish: Function
  ) {
    const jobResult
      = this.httpClient.get<Job>(this.urlComposer(JOB_BY_UID, jobId));
    jobResult.subscribe((job: Job) => {
      if (job.finished === null) {
        if (keepTrying) {
          // TODO: consider getting rid of recursion, it might should be a loop
          new Promise(
            resolve => setTimeout(resolve, interval)
          ).then(
            () => this.checkAsyncJob(jobId, interval, keepTrying, onFinish)
          );
        }
      } else {
        onFinish();
      }
    });
  }

Я хотел бы избежать рекурсии здесь , поскольку это (я полагаю) заставляет браузер потреблять все больше ОЗУ, пока работа не будет завершена. Есть ли способ переопределить его как al oop, учитывая, что httpClient.get() возвращает подписываемый объект и основной поток не ожидает его завершения?

Спасибо!

Ответы [ 2 ]

1 голос
/ 09 февраля 2020

Может быть retryWhen из Rx JS может решить вашу проблему. Это может быть что-то вроде

this.httpClient.get<Job>(this.urlComposer(JOB_BY_UID, jobId))
  .pipe(
    map((job: Job) => {
      if (job.finished === null) {
        throw job; // throw as an error so can be catched by retryWhen
      }

      return job;
    }),
    retryWhen(errors => {
      errors.pipe(
        // timer is a RxJS function
        delayWhen(() => timer(interval)) // restart again after interval 
      )
    })
  )
  .subscribe(onFinish);

Ссылка:

Надеюсь, это поможет

0 голосов
/ 08 февраля 2020

Rx JS есть все, что вам нужно. Не путайте и не используйте императивные if вместе с обещаниями, циклами, рекурсиями setTimeouts.

Чтобы решить вашу проблему, взгляните на эту статью

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...