角度7的下一个回调函数

问题描述 投票:0回答:1

作为一个初学者,我正在经历observables和promise之间的区别,有人说,一旦订阅者订阅,每次从http请求返回数据(Observable)时,它都可以获得对其下一个方法的回调。我无法重新创建这样的场景wheredata在流中返回,接下来被多次调用,我只能找到一个立即作为一个数据集返回的数组。有些人可以共享这样的场景,其中next()函数被多次调用单个请求。

angular callback angular5 angular7
1个回答
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()函数甚至会收到HttpProgressEvents,它表示上传或下载的字节数。

因此,在观察事件时,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,则会失去此保证。

© www.soinside.com 2019 - 2024. All rights reserved.