Задержка рекурсивного HTTP-запроса get внутри цикла do while в Angular 6 - PullRequest
0 голосов
/ 23 мая 2018

Я рекурсивно потребляю внешний API, ожидая завершения другого вызова API.HTTP-вызовы выполняются с использованием import {HttpClient} from '@angular/common/http'

. Я новичок в фреймворке и, возможно, в коде что-то не так, но рабочий процесс такой:

Первый APIвызов сделан этим блоком

initializeCrawling(): void {         
this.callCrawlInitializingAPI()       // this method is calling the api
  .subscribe(
    restItems => {
      this.groupCrawlingRestResponse = restItems;
      console.log(this.groupCrawlingRestResponse);
      this.isCrawlActive = false;
    }
  )

this.fetchResults();    // while callCrawlInitializingAPi call executes, this block here must executed on paralel.
}

Теперь я объявляю глобальную

логическую

переменную, которая станет false при this.callCrawlInitializingAPI() execute finish.

Вот код для второго вызова API, который должен вызываться рекурсивно.

fetchResults(): void {
this.fetchDataApiCall()
  .subscribe(
    restItems => {
      this.groupCrawlingRestResponse = restItems;
      console.log(this.groupCrawlingRestResponse);
    }
  )

}



fetchDataApiCall() {
    do {
      this.http
        .get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
        .pipe(map(data => data));
      console.log("Delaying 3000");
    } while (this.isCrawlActive);
  }

Цель здесь - задержать цикл do - while, скажем, на 1 секунду.

Я попробовал следующее: 1 - импортировать {delay} из "rxjs / internal / operator" и использовать, как указано выше;

do {
  this.http
    .get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
    .pipe(map(data => data));
  console.log("Delaying 3000");
  delay(3000);
} while (this.isCrawlActive);

2 - использовать функцию setTimeout (), как указано выше:

do {
 setTimeout(function(){
 this.http
 .get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
 .pipe(map(data => data));}, 1000)
 } while (this.isCrawlActive)

Ни один из них не работает, и, насколько я понимаю, цикл do while не задерживается и обрабатывает много вызовов, как do while.

Прежде всего яхочу знать, как заставить это работать и, во-вторых, есть ли лучший способ сделать это с Angular, так как яплохо знакомы с фреймворком.

Спасибо


ОБНОВЛЕНИЕ

На мой вопрос есть правильный ответ, если кто-нибудь будет искать его в будущем.

Единственное, что мне пришлось изменить, - это строка кода clearInterval(intervalHolder.id)

1 Ответ

0 голосов

Прежде всего, когда вы подписываетесь на функцию, содержащую http-событие, функция должна возвращать поток / http-вызов

fetchDataApiCall() {
  return this.http
    .get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
    .pipe(map(data => data));
  }

После этого, если вы хотите отложить ответ, вы должны поставитьоператор задержки в канале, вот так.

fetchDataApiCall() {
  return this.http
    .get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
    .pipe(map(data => data),
          delay(3000));
  }

ОБНОВЛЕНИЕ

Как отмечается в комментариях перед обновлением, существуют некоторые проблемы с чистым интервалом, поэтому вот 100% проверенное решение длядело.В первом блоке кода присутствует логика опроса, поскольку свойство isActive имеет значение true, каждый новый запрос будет вызываться каждые 500 мс.

Второй блок кода - это служба, которая имитируетзапросы.

export class ChildOne {
  longReqData;
  shortReqData = [];

  active = true;

  constructor(private requester: RequesterService) {}

  loadData() {
    this.requester.startLongRequest().subscribe(res => {
      this.longReqData = res;
      console.log(res);
      this.active = false;
    });

    let interval = Observable.interval(500);

    let sub = interval.subscribe(() => {
      this.requester.startShortRequest().subscribe(res => {
        this.shortReqData.push(res);
        console.log(res);
      });
      if (this.active === false) {
        sub.unsubscribe();
      }
    });
  }
}

@Injectable()
export class RequesterService {
  private counter = 0;
  stop() {
    this.subject.next(false);
  }
  startShortRequest() {
    this.counter += 1;
    let data = {
      delay: 0,
      payload: {
        json: this.counter
      }
    };
    return this.mockRequest(data);
  }

  startLongRequest() {
    let data = {
      delay: 3000,
      payload: {
        json: "someJSON"
      }
    };
    return this.mockRequest(data);
  }
  mockRequest(data) {
    return Observable.of(data).pipe(delay(data.delay));
  }
}
...