Angular RxJS subscribe和局部变量为null问题

Angular RxJS subscribe和局部变量为null问题,angular,rxjs,observable,Angular,Rxjs,Observable,我在Angular应用程序中编写了这个函数来调用RESTful服务,该类作为服务类位于组件之外 getProducts(): IProduct[] { let productsObservable = this.http.get<IProduct[]>(this.productUrl).pipe( tap(data => console.log("All: " + JSON.stringify(data))), catchError(th

我在Angular应用程序中编写了这个函数来调用RESTful服务,该类作为服务类位于组件之外

getProducts(): IProduct[] {
    let productsObservable = this.http.get<IProduct[]>(this.productUrl).pipe(
        tap(data => console.log("All: " + JSON.stringify(data))),
        catchError(this.serviceErrorHandler)
    );

    let products: IProduct[];
    let errorMessage: string = "";

    productsObservable.subscribe(
        p => {
            products = p;
            console.log("All in subscribe: " + JSON.stringify(products));
        },
        error => errorMessage = <any>error
    );

    if (errorMessage.length > 0) {
        console.log(errorMessage);
        throw new Error(errorMessage);
    }

    console.log("All before return: " + JSON.stringify(products));
    return products;
}
getProducts():ipproduct[]{
让productsObservable=this.http.get(this.productUrl.pipe)(
点击(data=>console.log(“All:+JSON.stringify(data)),
catchError(this.serviceErrorHandler)
);
let产品:IPProduct[];
let errorMessage:string=“”;
productsBServable.subscribe(
p=>{
产品=p;
log(“全部订阅:+JSON.stringify(产品));
},
错误=>errorMessage=错误
);
如果(errorMessage.length>0){
控制台日志(错误消息);
抛出新错误(errorMessage);
}
log(“返回之前的所有内容:+JSON.stringify(产品));
退货产品;
}
我有3行带有
console.log的代码来跟踪我的数据

  • tap
    函数中的第一个函数在控制台中显示了所有JSON数据,这意味着服务调用成功
  • my
    subscribe
    函数中的第二个函数也显示JSON负载
  • 但最后一次失败了。我为列表控制台日志函数设置了一个断点,发现变量
    products
    为空
如果Http Observable的使用者在同一服务类中,则结果为null。如果我将服务请求的使用者分解为Angular的组件类,它就可以正常工作。是什么让Rx的可观测性如此奇怪?我想我只要订阅它,它就会被执行


知道我的代码有什么问题吗?

是的,这是因为在返回
产品
列表之前没有调用传递给
订阅
的函数

考虑一个更简单的例子:

function f() {
    let flag: boolean = false;

    setTimeout(() => flag = true, 10);

    return flag;
}
使用
setTimeout
,您可以将一个新任务放到上,就像使用
http.get
一样。事件循环中的任务总是在将它们放在那里的函数返回后执行。在我的示例中,无论超时值有多低,返回值总是
false

回到您的示例,您需要的是从函数返回一个可观察的
。您可以直接返回GET调用,而不是将GET调用的返回值分配给本地
products
变量。像这样:

getProducts(): Observable<IProduct[]> {
    // your get call ...
    return productsObservable;
}
getProducts():可观察{
//你的电话。。。
返回可服务的产品;
}
现在,这可能不会为您解决所有问题,因为您现在需要处理消费函数中可观察的
。但这或多或少是整个可观察模式的要点。。将数据更改通知最终使用者


在Angular中,您可以处理观测值。

此函数在您的服务文件或组件文件中吗?这是我的服务文件中的函数。我明白您在这里所说的内容。我试图在同一个类中将我的函数分成2个,但仍然不起作用。但是,如果我将可观察的消费代码移动到我的组件类中,它就会工作。我不太明白为什么。基本上,如果你想使用一个可观察的,你必须把它传递给你的最终消费者,在你的例子中是角度分量。那么我的最终消费者在同一个类中呢?你可能想发布修改过的代码,在那里你已经把你的原始函数一分为二。修订后的准则中也可能存在同样的问题。您的第二个函数可能已经订阅了第一个函数,但第二个函数甚至在“subscribe”从第一个函数接收数据之前返回。