Следующая функция обратного вызова в угловых 7 - PullRequest
0 голосов
/ 05 марта 2019

Будучи новичком, я проходил различие между наблюдаемыми и обещаниями, и каждый говорит, что как только подписчик подписан, он может получить обратный вызов своего следующего метода каждый раз, когда данные (Observable) возвращаются из запроса http.Я не могу воссоздать такой сценарий, когда данные возвращаются в потоках, а затем вызывается несколько раз, все, что я мог найти, - это массив, который немедленно возвращается как один набор данных.Может ли кто-нибудь поделиться таким сценарием, когда функция next () вызывается несколько раз для одного запроса.

1 Ответ

0 голосов
/ 05 марта 2019

Редактировать

Это зависит от опции observe, о которой я забыл в своем первоначальном ответе.

Observable<Book> = httpClient.get<Book>('/api/books/1', {
  observe: 'body'     // Default
});
Observable<HttpResponse<Book>> = httpClient.get<Book>('/api/books/1', {
  observe: 'response'
});
Observable<HttpEvent<Book>> = httpClient.get<Book>('/api/books/1', {
  observe: 'events',
  reportProgress: true,
  responseType: 'json'
});

По умолчанию next() - этовызывается с телом ответа, но вы можете изменить его с помощью опции observe.

С помощью 'response' Angular передает весь ответ со статусом, заголовками, телом и т. д. на next().Это по-прежнему происходит не более одного раза для каждого запроса.

При 'events' Angular информирует вас о нескольких интересных событиях обмена запросом-ответом, передав соответствующий HttpEvent в next().Например, HttpSentEvent указывает, что запрос был отправлен полностью.У HttpHeaderResponse есть все заголовки ответа, но нет содержимого.

Если вы также используете reportProgress: true, ваша функция next() будет даже получать HttpProgressEvent с, которые указывают, сколько байтов загружено или загружено.

Таким образом, при наблюдении за событиями next() действительно будет вызываться несколько раз.

В моем исходном ответе ниже я предполагаю, что вы наблюдаете тело.Ответ

Что касается результирующего Observable HTTP-запроса, вы правы, каждая функция next() будет вызываться не более одного раза.

Однако,Вы можете использовать несколько операторов RxJS для преобразования результирующего Observable в другой оператор, функция которого next() будет вызываться чаще.

Несколько примеров:

this.httpClient.get('/api/books/1').pipe(
  map(book => book.title),
  startWith('Initial value')
).subscribe({
  // Will be called twice: First with "Initial value", then with actual book title
  next: title => console.log(title)
});

this.httpClient.get('/api/books/1').pipe(
  repeat(3)  // Results in 3 requests
).subscribe({
  // Will be called 3 times, once for each request
  next: book => console.log(book)
});

// Suppose bookIdChanges is a Subject<number> that changes whenever
// the user selects another book
this.bookIdChanges.pipe(
  // Whenever the ID changes, the corresponding book is loaded from the server.
  // A previous request will be cancelled.
  switchMap(id => this.httpClient.get('/api/books/${id}'))
).subscribe({
  // Will be called whenever the ID changes, unless it changes again before
  // the response has arrived.
  next: book => console.log(book)
});

Это может быть очевиднымчто next() вызывается здесь несколько раз, если вы знаете задействованные операторы.

Но в реальном проекте HTTP-запросы обычно выполняются в сервисных методах.Например, давайте переместим композицию bookIdChanges и HTTP-запрос из последнего примера в класс обслуживания:

@Injectable()
export class BookService {

  private bookIdChanges = new Subject<number>();

  constructor(private: HttpClient) { }

  public selectAsCurrentBook(id: number): void {
    bookIdChanges.next(id);
  }

  public getCurrentBook(): Observable<Book> {
    return this.bookIdChanges.pipe(
      switchMap(id => this.httpClient.get<Book>('/api/books/${id}'))
    );
  }
}

Затем мы используем его в таком компоненте, как:

this.postsService.getCurrentBook().subscribe(book => {
  // ... do something with book
});

По-прежнему существует несколько запросов и несколько вызовов next(), но теперь все это скрыто внутри метода службы.Это хорошо, но вы должны четко указать это в названии и / или документации метода сервиса.

Вывод: да, HTTP-запрос возвращает Observable, который испускается не более одного раза., но если вы не подписываетесь на него напрямую, а скорее на преобразованный Observable, вы теряете эту гарантию.

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