gpt4 book ai didi

Angular 4 和 RxJS 5 : Observable. concat() 行为异常

转载 作者:搜寻专家 更新时间:2023-10-30 21:39:36 26 4
gpt4 key购买 nike

我的 Angular 4/TypeScript 2.3 服务有一个函数 build() 如果类属性没有被初始化就会出错。我正在尝试构建一个更安全的版本——safeBuild()——它将返回一个 Observable,它会在尝试调用 build()< 之前等待并监听要初始化的属性

export class BuildService {

renderer:Renderer2; // must be set for build() below to work

// emits the new Renderer2 when renderer is set
private rendererSet$:BehaviorSubject<Renderer2> = new BehaviorSubject(null);

/** Set renderer, and notify any listener */
setRenderer(renderer:Renderer2){
this.renderer = renderer;
this.rendererSet$.next(renderer);
}

/** Returns a new DOM element. Requires renderer to be set */
build(elemTag:string){
// if renderer is not set, we can't proceed
// why is this error thrown when safeBuild() is called?
if (!this.renderer)
throw new Error('Renderer must be set before build() is run');

return this.renderer.createElement(elemTag);
}

/**
* A safe version of build(). Will wait until renderer is set
* before attempting to call build (Asynchronous)
*/
safeBuild(elemTag:string):Observable<any> {
// inform user that renderer should be set
// this warning is printed to the console as expected
if (!this.renderer)
console.warn('The build will be delayed until setRenderer() is called');

// Listen to rendererSet$, filter out the null output, and call build()
// only once the renderer is set. Why does the error still get thrown?
return Observable.concat(
this.rendererSet$.filter(e=>!!e).take(1),
Observable.of(this.build(elemTag))
)
}
}

我尝试像这样构建(从另一个服务):

this.buildService.safeBuild(elemTag).subscribe(...)

在控制台中我看到:

Warn: The build will be delayed until setRenderer() is called

Error: Renderer must be set before build() is run

我预料到会收到警告,但直到我的应用程序的另一部分调用 setRenderer() 时才发生任何事情。届时,subscribe() 中的代码将运行。

为什么我会看到错误?

最佳答案

问题是 this.build(elemTag) 在组合 concat 可观察对象时被调用 - 而不是在执行连接时调用。

您可以使用 defer 解决问题:

import 'rxjs/add/observable/defer';

...
return Observable.concat(
this.rendererSet$.filter(e => !!e).take(1),
Observable.defer(() => Observable.of(this.build(elemTag)))
);

或者,正如评论中指出的那样,使用 map:

return this.rendererSet$
.filter(e => !!e)
.take(1)
.map(() => this.build(elemTag));

关于Angular 4 和 RxJS 5 : Observable. concat() 行为异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45001179/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com