首页 > 解决方案 > 错误:使用“defer”时“observableFactory 不是函数”

问题描述

我创建了一个 Angular 9 指令,该指令仅在用户通过身份验证时才显示 HTMl 元素:

<div *authenticated>
  Message for Members
</div>

指令代码是:

@Directive({
  selector: '[authenticated]'
})

export class AuthenticatedDirective implements OnInit, OnChanges {

  constructor(private template: TemplateRef<any>, private container: ViewContainerRef, private authenticationService: AuthenticationService) { }

  ngOnInit() {

    this.authenticationService.isSignedIn().subscribe(x => {
      x ? this.container.createEmbeddedView(this.template) : this.container.clear();
    });

  }

  ngOnChanges() { 

    this.authenticationService.isSignedIn().pipe(
      distinctUntilChanged()
    ).subscribe(x => {
      x ? this.container.createEmbeddedView(this.template) : this.container.clear();
    });

  }

}

当我运行代码时,我收到错误:

TypeError: observableFactory is not a function. (In 'observableFactory()', 'observableFactory' is an instance of ZoneAwarePromise) — defer.js:8

我检查了authenticationService.isSignedIn()方法,我有:

isSignedIn(): Observable<boolean> {

  return defer(this.manager.getUser()).pipe(map((user: User) => !user.expired));

}

该方法this.manager.getUser()返回 aPromise<User>所以我defer用来返回一个Observable.

如果我defer改为from然后它工作...

但我不应该使用defer吗?

标签: angularrxjsobservableangular9

解决方案


你只是用defer()错了方法。它将回调作为每次新观察者订阅时调用的参数。当您使用它时,defer(this.manager.getUser())它试图将返回值getUser()用作一种方法,我猜它不是,所以它会引发错误。

相反,您应该像这样使用它:

defer(() => this.manager.getUser())

现在每个新订阅都会调用这个方法并defer()订阅它。我不知道你是否应该使用它。这取决于getUser()内部做什么。如果它总是返回相同的 Observable 那么你不需要defer. 如果它返回不同的 Observables(例如使用不同的参数发出 HTTP 请求),那么您需要使用defer().


推荐阅读