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
,您将失去此保证。
作为初学者,我正在研究可观察对象和承诺之间的区别,有人说一旦订阅者被订阅,每次从 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
,您将失去此保证。