Observable 的异步行为导致变量未定义

Posted

技术标签:

【中文标题】Observable 的异步行为导致变量未定义【英文标题】:Asynchronous behavior of Observable causing variable to be undefined 【发布时间】:2017-04-08 00:06:12 【问题描述】:

我在 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() 方法中,并且想要提取第一个 product 并放置在 ngOnInit() 中。

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 组件中进行插值。 我希望提取是自动的。那你能给我一个方法吗?

【问题讨论】:

【参考方案1】:

由于您使用的是 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
  );

【讨论】:

【参考方案2】:

您实际上回答了您自己的问题 - 因为它是异步的,所以您对 this.product = ... 的调用会立即被调用,而 observable 需要一些时间才能返回。解决方法很简单:

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);

在可观察回调中包含集合。

【讨论】:

谢谢。还有一件事,我们可以在快乐路径中嵌入一些逻辑吗? @ShubhashishMishra 绝对!你可以在 observable 的回调中做任何你想做的事情。请记住,它是异步发生的——所以它在服务返回时发生,而不是立即发生。【参考方案3】:

你的代码:

this.product = this.products[0];

在定义之前被执行。将其移至您的成功功能中

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 的异步行为导致变量未定义的主要内容,如果未能解决你的问题,请参考以下文章

以下链式赋值是不是会导致未定义的行为?

导致非标准行为的 #pragma 是不是会导致 __STDC__ 宏未定义为 1?

C++ 类型索引散列导致未定义的行为

别名可变原始指针 (*mut T) 会导致未定义的行为吗?

SwiftUI 计算属性显示“在视图更新期间修改状态,这将导致未定义的行为。”错误

OpenFoam:更改 STL 位置会导致未定义行为或崩溃