Typescript + Angular2:订阅可观察的原因"无法识别的拆解1"错误

时间:2016-08-07 22:09:35

标签: typescript angular rxjs

我在Angular2.rc.4 Typescript应用程序中使用Observable时遇到问题。我在这里有一个plunker: https://embed.plnkr.co/UjcdCmN6hSkdKt27ezyI/

基本上,应用程序有一个具有以下代码的服务:

private messageSender : Observable<string>;

constructor() {
    this.messageSender = Observable.create(observer => this.clients.push(observer));
 }

public listenForMessages() : any {
    console.log("Listen Requested...")
    return this.messageSender;
}

我想从一个组件中听取它:

ngOnInit() {
    this.chatter.listenForMessages().subscribe(msg => console.log(msg));
}

这给了我以下错误:

EXCEPTION: Error: Unrecognized teardown 1 added to Subscription.
Error: Unrecognized teardown 1 added to Subscription.
    at Subscriber.Subscription.add (Subscription.ts:151)
    at Observable.subscribe (Observable.ts:93)
    at LoginPage.ngOnInit (login.ts:15)
    at DebugAppView._View_LoginPage_Host0.detectChangesInternal (LoginPage.template.js:29)
    at DebugAppView.AppView.detectChanges (view.ts:261)
    at DebugAppView.detectChanges (view.ts:377)
    at DebugAppView.AppView.detectContentChildrenChanges (view.ts:280)
    at DebugAppView.AppView.detectChangesInternal (view.ts:272)
    at DebugAppView.AppView.detectChanges (view.ts:261)
    at DebugAppView.detectChanges (view.ts:377)
BrowserDomAdapter.logError @ browser_adapter.ts:82

如果使用transile tsc或允许在浏览器中执行此操作,并且我以ES6或ES5为目标,则会发生同样的错误。

我已经看了几个小时,我发现在其他任何网站上都没有引用它。该错误消息来自RxJS,它检查传入.subscribe()方法的内容,检查其类型是否为&#39; object&#39;或者&#39;功能&#39;如果不是,则会发出此错误。我已经传递了lambda作为plunker或预定义的函数,它们会导致同样的问题。

有什么想法吗?如果我在组件中创建Observable,那么没有问题。如果我在服务中订阅,那么我会得到同样的错误......很困惑。

2 个答案:

答案 0 :(得分:4)

对于有类似错误消息的其他人。您可能没有将Object.create回调函数传递给TeardownLogic。地点:

export type TeardownLogic = AnonymousSubscription | Function | void;

export interface AnonymousSubscription {
  unsubscribe(): void;
}

例如,我正在返回boolean

this.showSomething = Observable.create((observer: Observer<boolean>) => this.code === "00108");

当我应该返回AnonymousSubscription时:

this.showSomething = Observable.create((observer: Observer<boolean>) => {
    observer.next(this.code === "00108");
});

答案 1 :(得分:2)

您的问题是,Array#push会返回一个数字(这是Array的新长度),当您执行TeardownLogic时,它会尝试将其用作新的Observable.create(observer => this.clients.push(observer)) }}

我建议你使用 observer-array 模式,你只是诚实地重新发明轮子,你不太可能正确地做到这一点(*注意:它不仅仅是你,我已经看到它出现在ng2教程中,它只是一个糟糕的,可怕的模式。)

如果您需要多播行为,则应使用Subject代替:

private messageSender : Subject<string>;

constructor() {
    this.messageSender = new Subject<string>();
 }

public listenForMessages() : any {
    console.log("Listen Requested...")
    return this.messageSender.asObservable();
}

更好的解决方案是完全取消中间Subject并直接订阅消息来源,但如果不了解更多有关您的应用程序的信息,我实际上并不能说你如何解决这个问题。