Rxjs дождитесь ответа и снова запустите метод

#javascript #angular #typescript #rxjs

Вопрос:

У меня есть код, который проверяет статус , и если статус отсутствует Completed или Failed , повторите вызов

Вот код

 getRecognitionById() {  this.loaderService.show(null, true);  this.vendorWebApiService  .createRecognition(this.executiveChangeId)  .pipe(take(1))  .subscribe((res) =gt; {  this.refresher$ = interval(5000);  this.refreshSub = this.refresher$.subscribe(() =gt; {  this.checkStatus(res.taskRequestId);  if (this.jobStatus === "Completed") {  this.refreshSub.unsubscribe();  this.getLatestFeedback();  this.loaderService.hide(true);  }  if (this.jobStatus === "Failed") {  this.loaderService.hide(true);  this.refreshSub.unsubscribe();  alert("Recognition failed. Try again later");  } else {  if (this.checkCount lt; 36) {  this.checkStatus(res.taskRequestId); //run check status again only when we get response  } else {  this.loaderService.hide(true);  this.refreshSub.unsubscribe();  alert("Recognition failed. Try again later");  }  }  });  });  }  

Мне нужно дождаться ответа от checkStatus() метода и только затем запустить checkStatus() снова (я прокомментировал часть кода, в которой мне нужно выполнить эту логику)

Вот код checkStatus метода

 checkStatus(taskRequestId: number) {  this.checkCount  ;  this.vendorWebApiService  .getRecognition(taskRequestId, this.executiveChangeId)  .pipe(take(1))  .subscribe((recognitionResponse) =gt; {  this.jobStatus = recognitionResponse.jobStatus;  if (recognitionResponse.jobStatus === "Completed") {  this.recognitionData = recognitionResponse;  }  });  }  

Как я могу этого достичь?

Комментарии:

1. здесь полезно использовать оператор трубы rxjs, такой как switchMap ().

2. Можете ли вы показать, как и где мне нужно его использовать? @ГаурангДхорда

3. сначала сделайте демонстрацию этого кода с помощью stackblitz, чтобы было более полезно его понять

Ответ №1:

У вас в коде много лишних битов, поэтому я сомневаюсь, что это будет компилироваться как есть. Тем не менее, вот идея для чего-то, что должно сработать, если вы устраните неполадки.

 // By returning an observable that emits once the status is checked, // we use emission to know when the status is checked. checkStatus(taskRequestId: number): Observablelt;Statusgt; {   return this.vendorWebApiService.getRecognition(  taskRequestId,   this.executiveChangeId  ).pipe(   take(1),   /* This info is emitted directly into your stream now, so  // you shouldn't need to se global variables here anymore.  // uncomment this to get those gloabls being set again.  // Up to you.   tap(recognitionResponse =gt; {  this.jobStatus = recognitionResponse.jobStatus;  if (recognitionResponse.jobStatus === "Completed") {  this.recognitionData = recognitionResponse;  }  })  */  );  }  getRecognitionById() {   this.loaderService.show(null, true);   this.vendorWebApiService.createRecognition(this.executiveChangeId).pipe(   switchMap(res =gt; this.checkStatus(res.taskRequestId).pipe(   tap(({jobStatus}) =gt; {  if (jobStatus !== "Completed" amp;amp; jobStatus !== "Failed") {  throw "This is an error we can catch and retry with";  }  }),   // If there's an error try again  retryWhen(errors =gt; errors.pipe(  take(36), // Retry a max of 36 times  s =gt; concat(s, defer(() =gt; {  // After 36 retry attempts, we still failed  this.loaderService.hide(true);  alert("Recognition failed. Try again later");  return EMPTY;  })),  delay(5000) // Wait 5 seconds before retry  ))  )),   take(1)   ).subscribe(recognitionResponse =gt; {   const {jobStatus} = recognitionResponse;   if (jobStatus === "Completed") {  this.recognitionData = recognitionResponse;  this.getLatestFeedback();  }   if (jobStatus === "Failed") {  alert("Recognition failed. Try again later");  }   this.loaderService.hide(true);   }); }