Observable 的异步行为导致变量未定义
Asynchronous behavior of Observable causing variable to be undefined
我在 Angular2 中创建了一个服务,它负责对 java 服务进行 REST 调用,并使用 HTTP Observable 获取产品数组。
getAll(): Observable<Product[]>{
let data$ = this.http
.get(`${this.baseUrl}/productdata`, {headers: this.getHeaders()})
.map(mapData)
.catch(handleError);
console.log(' object array:' , data$)
return data$;
}
然后我在我的组件中为这个 Observable 编写了一个订阅者,并将其放置在 ngOnInit() 方法中,并且只想提取放置在 ngOnInit() 中的第一个 product。
this.product = this.products[0];
ngOnInit() {
this.productService
.getAll()
.subscribe(
/* happy path */ p => this.products = p,
/* error path */ e => this.errorMessage = e,
/* onComplete */ () => this.isLoading = false);
this.product = this.products[0];
}
但是由于 Observable 的异步行为,OnInit 方法中的最后一个操作导致 product 未定义。同样,我无法使用 product 的 属性 来插入 HTML 组件。
我希望提取是自动的。那你能给我一个方法吗?
您的代码:
this.product = this.products[0];
在定义之前正在执行。把它移到你的 on success 函数中
this.productService
.getAll()
.subscribe(
/* happy path */ p => {
this.products = p;
this.product = this.products[0];
},
/* error path */ e => this.errorMessage = e,
/* onComplete */ () => this.isLoading = false
);
您实际上回答了您自己的问题 - 因为它是异步的,所以您对 this.product = ...
的调用会立即被调用,而可观察对象 return 需要一些时间。解决方法很简单:
ngOnInit() {
this.productService
.getAll()
.subscribe(
/* happy path */ p => {
this.products = p;
this.product = this.products[0];
},
/* error path */ e => this.errorMessage = e,
/* onComplete */ () => this.isLoading = false);
}
将集合包含在可观察的回调中。
由于您使用的是 observable,因此您可以利用 observable 的所有方法,例如您已经在使用的 .map() 函数。
this.productService
.getAll()
.map(products => products[0])
.subscribe(
/* happy path */ product => this.product = product,
/* error path */ e => this.errorMessage = e,
/* onComplete */ () => this.isLoading = false
);
我在 Angular2 中创建了一个服务,它负责对 java 服务进行 REST 调用,并使用 HTTP Observable 获取产品数组。
getAll(): Observable<Product[]>{
let data$ = this.http
.get(`${this.baseUrl}/productdata`, {headers: this.getHeaders()})
.map(mapData)
.catch(handleError);
console.log(' object array:' , data$)
return data$;
}
然后我在我的组件中为这个 Observable 编写了一个订阅者,并将其放置在 ngOnInit() 方法中,并且只想提取放置在 ngOnInit() 中的第一个 product。
this.product = this.products[0];
ngOnInit() {
this.productService
.getAll()
.subscribe(
/* happy path */ p => this.products = p,
/* error path */ e => this.errorMessage = e,
/* onComplete */ () => this.isLoading = false);
this.product = this.products[0];
}
但是由于 Observable 的异步行为,OnInit 方法中的最后一个操作导致 product 未定义。同样,我无法使用 product 的 属性 来插入 HTML 组件。 我希望提取是自动的。那你能给我一个方法吗?
您的代码:
this.product = this.products[0];
在定义之前正在执行。把它移到你的 on success 函数中
this.productService
.getAll()
.subscribe(
/* happy path */ p => {
this.products = p;
this.product = this.products[0];
},
/* error path */ e => this.errorMessage = e,
/* onComplete */ () => this.isLoading = false
);
您实际上回答了您自己的问题 - 因为它是异步的,所以您对 this.product = ...
的调用会立即被调用,而可观察对象 return 需要一些时间。解决方法很简单:
ngOnInit() {
this.productService
.getAll()
.subscribe(
/* happy path */ p => {
this.products = p;
this.product = this.products[0];
},
/* error path */ e => this.errorMessage = e,
/* onComplete */ () => this.isLoading = false);
}
将集合包含在可观察的回调中。
由于您使用的是 observable,因此您可以利用 observable 的所有方法,例如您已经在使用的 .map() 函数。
this.productService
.getAll()
.map(products => products[0])
.subscribe(
/* happy path */ product => this.product = product,
/* error path */ e => this.errorMessage = e,
/* onComplete */ () => this.isLoading = false
);