angular 7中的下一个回调函数

时间:2019-03-05 02:58:46

标签: angular callback angular5 angular7

作为一个初学者,我经历了可观察值和promise之间的区别,有人说,一旦订阅者被订阅,每次从http请求返回data(Observable)时,它都可以回调其下一个方法。我无法重新创建这样一种场景,即数据在流中返回,然后多次被调用,我所能找到的只是一个数组,该数组立即作为一个数据集返回。有人可以分享这样的情形吗?next()函数被单个请求多次调用。

1 个答案:

答案 0 :(得分:1)

修改

这取决于我在原始答案中忘记的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()确实会被多次调用。

在下面的原始答案中,我假设您观察身体。

原始答案

就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请求的组成移到服务类中:

@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,您将失去此保证。