您如何处理 Angular 中的函数顺序?
How do you handle the order of functions in Angular?
所以我有一个 Angular 组件。
我想使用一些包含数据的数组对象:
books: Book[] = [];
reviews: Review[] = [];
这是我的 ngOnInit() 的样子:
ngOnInit(): void {
this.retrieveBooks();
this.retrieveReviews();
this.setRatingToTen();
}
我以此为对象数组编写书籍和评论。
这是通过服务“订阅”数据来完成的:
retrieveBooks(): void {
this.bookService.getAll()
.subscribe(
data => {
this.books = data;
},
error => {
console.log(error);
}
);
}
retrieveReviews(): void {
this.reviewService.getAll()
.subscribe(
data => {
this.reviews = data;
},
error => {
console.log(error);
});
}
所以我的下一个函数只是“处理数据”的一个例子。
在此示例中,我只想将每本书的所有总评分更改为 10:
setRatingToTen(): void {
this.books.forEach(element => {
element.totalrating = 10;
});
console.log(this.books);
}
我一直想解决的问题是:
this.books 是一个空数组.
我想是因为这个功能在数据订阅之前运行。
如果是这样,那我对ngOnInit的理解一定不对
我以为它会按顺序调用函数。
也许还是这样,只是没有按顺序完成。
所以我的问题是:
1.为什么是空数组?
(我说的对吗?还是还有其他的?)
2。 Angular 开发人员如何编写函数以使其按所需顺序运行?
(因为数据需要存在以便我可以使用它,我该如何避免这个问题?)
(3.) 奖金问题:
(如果有空请多谢)
我的目标是为每本 this.reviews.title 等于 this.books.title 的书拉 this.reviews.rating,得到平均分;然后用平均值覆盖 this.books.totalrating 的“0”占位符。我如何重写 setRatingToTen() 函数来完成此操作?
这是在 rxjs 中使用 forkJoin 方法的解决方案之一。
工作演示:enter link description here
ngOnInit:
ngOnInit(){
this.requestDataFromMultipleSources().subscribe(resList => {
this.books = resList[0];
this.reviews = resList[1];
this.setRatingToTen(this.books,this.reviews);
})
}
forkJoin 方法:
public requestDataFromMultipleSources(): Observable<any[]> {
let response1 = this.retrieveBooks();
let response2 = this.retrieveReviews();
// Observable.forkJoin (RxJS 5) changes to just forkJoin() in RxJS 6
return forkJoin([response1, response2]);
}
其他方法:
retrieveBooks(): void {
this.bookService.getAll()
.subscribe(
data => {
this.books = data;
},
error => {
console.log(error);
}
);
}
retrieveReviews(): void {
this.reviewService.getAll()
.subscribe(
data => {
this.reviews = data;
},
error => {
console.log(error);
});
}
setRatingToTen(books, reviews): void {
this.books.forEach(element => {
element.totalrating = 10;
});
console.log(this.books);
}
Angular 大量使用 observables 来处理各种 异步 操作。发出服务器端请求(通过 HTTP)就是其中之一。
您的前两个问题清楚地反映出您忽略了 可观察对象的异步性质。
Observables are lazy Push collections of multiple values. detailed link
意味着可观察到的响应将以异步方式随时间推送。您无法保证这两个不同函数中的哪一个会 return 首先响应。
话虽如此,rxjs 库(Observables 也是这个库的一部分,angular 从这里借来的)提供了丰富的 可用于 操纵可观察对象 .
的运算符
有了上面的解释,下面就为大家一一解答。
1.为什么是空数组?
因为您考虑的是同步顺序代码流,其中一种方法只有在另一种方法完成其工作后才会被调用。但是这里 retrieveBooks 和 retrieveReviews 都在进行 asynchronous (可观察)调用,然后订阅它。这意味着无法保证何时会收到他们的回复。同时对 setRatingToTen 的命中已经完成,在那个时间点 books 数组是空的。
2。 Angular 开发人员如何编写函数以便它们按所需顺序运行?
Angular 开发人员会理解 异步可观察 调用的性质,并且会 pipe 运算符在一个顺序中,以便在对可观察流执行任何进一步操作之前,他们确定他们已经掌握了响应。
(3.) 奖金问题:
您的要求指定在执行任何操作之前,您必须首先获得手头两个可观察对象的响应。 forkJoin rxjs 运算符适合您的需要。该运算符的文档说
One common use case for this is if you wish to issue multiple requests on page load (or some other event) and only want to take action when a response has been received for all. detailed link
不确定您的平均得分策略,但这里有一个示例代码可以帮助您实现目标。
ngOnInit(){
let req1$ = this.bookService.getAll();
let req2$ = this.reviewService.getAll();
forkJoin(req1$, req2$).subscribe(([response1, response2])=>{
for(let book of response1) //loop through book array first
{
for(let review of response2) //inner loop of reviews
{
if(book.title == review.title)
{
//complete your logic here..
}
}
}
});
}
所以我有一个 Angular 组件。
我想使用一些包含数据的数组对象:
books: Book[] = [];
reviews: Review[] = [];
这是我的 ngOnInit() 的样子:
ngOnInit(): void {
this.retrieveBooks();
this.retrieveReviews();
this.setRatingToTen();
}
我以此为对象数组编写书籍和评论。 这是通过服务“订阅”数据来完成的:
retrieveBooks(): void {
this.bookService.getAll()
.subscribe(
data => {
this.books = data;
},
error => {
console.log(error);
}
);
}
retrieveReviews(): void {
this.reviewService.getAll()
.subscribe(
data => {
this.reviews = data;
},
error => {
console.log(error);
});
}
所以我的下一个函数只是“处理数据”的一个例子。
在此示例中,我只想将每本书的所有总评分更改为 10:
setRatingToTen(): void {
this.books.forEach(element => {
element.totalrating = 10;
});
console.log(this.books);
}
我一直想解决的问题是:
this.books 是一个空数组.
我想是因为这个功能在数据订阅之前运行。
如果是这样,那我对ngOnInit的理解一定不对
我以为它会按顺序调用函数。
也许还是这样,只是没有按顺序完成。
所以我的问题是:
1.为什么是空数组?
(我说的对吗?还是还有其他的?)
2。 Angular 开发人员如何编写函数以使其按所需顺序运行?
(因为数据需要存在以便我可以使用它,我该如何避免这个问题?)
(3.) 奖金问题:
(如果有空请多谢)
我的目标是为每本 this.reviews.title 等于 this.books.title 的书拉 this.reviews.rating,得到平均分;然后用平均值覆盖 this.books.totalrating 的“0”占位符。我如何重写 setRatingToTen() 函数来完成此操作?
这是在 rxjs 中使用 forkJoin 方法的解决方案之一。
工作演示:enter link description here
ngOnInit:
ngOnInit(){
this.requestDataFromMultipleSources().subscribe(resList => {
this.books = resList[0];
this.reviews = resList[1];
this.setRatingToTen(this.books,this.reviews);
})
}
forkJoin 方法:
public requestDataFromMultipleSources(): Observable<any[]> {
let response1 = this.retrieveBooks();
let response2 = this.retrieveReviews();
// Observable.forkJoin (RxJS 5) changes to just forkJoin() in RxJS 6
return forkJoin([response1, response2]);
}
其他方法:
retrieveBooks(): void {
this.bookService.getAll()
.subscribe(
data => {
this.books = data;
},
error => {
console.log(error);
}
);
}
retrieveReviews(): void {
this.reviewService.getAll()
.subscribe(
data => {
this.reviews = data;
},
error => {
console.log(error);
});
}
setRatingToTen(books, reviews): void {
this.books.forEach(element => {
element.totalrating = 10;
});
console.log(this.books);
}
Angular 大量使用 observables 来处理各种 异步 操作。发出服务器端请求(通过 HTTP)就是其中之一。
您的前两个问题清楚地反映出您忽略了 可观察对象的异步性质。
Observables are lazy Push collections of multiple values. detailed link
意味着可观察到的响应将以异步方式随时间推送。您无法保证这两个不同函数中的哪一个会 return 首先响应。
话虽如此,rxjs 库(Observables 也是这个库的一部分,angular 从这里借来的)提供了丰富的 可用于 操纵可观察对象 .
的运算符有了上面的解释,下面就为大家一一解答。
1.为什么是空数组?
因为您考虑的是同步顺序代码流,其中一种方法只有在另一种方法完成其工作后才会被调用。但是这里 retrieveBooks 和 retrieveReviews 都在进行 asynchronous (可观察)调用,然后订阅它。这意味着无法保证何时会收到他们的回复。同时对 setRatingToTen 的命中已经完成,在那个时间点 books 数组是空的。
2。 Angular 开发人员如何编写函数以便它们按所需顺序运行?
Angular 开发人员会理解 异步可观察 调用的性质,并且会 pipe 运算符在一个顺序中,以便在对可观察流执行任何进一步操作之前,他们确定他们已经掌握了响应。
(3.) 奖金问题:
您的要求指定在执行任何操作之前,您必须首先获得手头两个可观察对象的响应。 forkJoin rxjs 运算符适合您的需要。该运算符的文档说
One common use case for this is if you wish to issue multiple requests on page load (or some other event) and only want to take action when a response has been received for all. detailed link
不确定您的平均得分策略,但这里有一个示例代码可以帮助您实现目标。
ngOnInit(){
let req1$ = this.bookService.getAll();
let req2$ = this.reviewService.getAll();
forkJoin(req1$, req2$).subscribe(([response1, response2])=>{
for(let book of response1) //loop through book array first
{
for(let review of response2) //inner loop of reviews
{
if(book.title == review.title)
{
//complete your logic here..
}
}
}
});
}