angular 7 中的下一个回调函数

Next callback function in angular 7

作为初学者,我正在研究可观察对象和承诺之间的区别,有人说一旦订阅者被订阅,每次从 http 请求返回数据 (Observable) 时,它都可以获得对其 next 方法的回调。我无法重新创建数据在流中返回并且 next 被多次调用的场景,我所能找到的只是一个数组,它立即作为一个数据集返回。有人可以分享这样的场景吗 next() 函数被多次调用单个请求。

编辑

这取决于 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() 会通过响应 body 调用,但您可以使用 observe 选项更改它。

对于 'response',Angular 将带有状态 headers、body 等的整个响应传递给 next()。对于每个请求,这仍然最多发生一次。

'events' 一起,Angular 通过将相应的 HttpEvent 传递给 next() 来通知您 request-response 交易所的几个有趣事件。 例如,HttpSentEvent 表示请求已发送完毕。 HttpHeaderResponse 包含所有响应 headers,但没有内容。

如果您还使用 reportProgress: true,您的 next() 函数甚至会收到 HttpProgressEvent 指示上传或下载的字节数。

所以在观察事件的时候,next()确实会被调用多次

在我下面的原始回答中,我假设您观察到 body。

原答案

就 HTTP 请求的结果 Observable 而言,你是对的,每个 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 请求移动到服务 class:

@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() 的多次调用,但现在这些都隐藏在一个服务方法中。 这是好事,但你应该在服务方法的文档中and/or 的名称中说清楚。

要点是,是的,一个 HTTP 请求 returns 一个 Observable 最多发出一次,但如果你不是直接订阅它,而是订阅一个转换后的 Observable,您将失去此保证。