summary
EventEmitter should also resolve onError and onComplete asynchronously for both onError and onComplete.
problem
On the server, I'm running into a problem EventEmitter because onComplete is called before onNext
export class EventEmitter extends Observable {
_subject = new Subject();
observer(generator: any): any {
return this._subject.subscribe((value) => { setTimeout(() => generator.next(value)); },
(error) => generator.throw ? generator.throw(error) : null,
() => generator.return ? generator.return () : null);
}
toRx(): any { return this; }
next(value: any) { this._subject.next(value); }
throw(error: any) { this._subject.error(error); }
return (value?: any) { this._subject.complete(); }
should be
export class EventEmitter extends Observable {
_subject = new Subject();
observer(generator: any): any {
return this._subject.subscribe((value) => { setTimeout(() => generator.next(value)); },
(error) => generator.throw ? setTimeout(() => generator.throw(error)) : null,
() => generator.return ? setTimeout(() => generator.return()) : null);
}
toRx(): any { return this; }
next(value: any) { this._subject.next(value); }
throw(error: any) { this._subject.error(error); }
return (value?: any) { this._subject.complete(); }
}
current workaround
include setTimeout for onError and onComplete
background/why
as far as I know, setTimeout was added in order for zone.js to pick up any changes. The problem is that onComplete resolves first without this change since onNext is push to the event loop. If you have any dispose logic in the onComplete callback then whatever obj you're working with may not work during the onNext callback. For example
ObservableWrapper
.subscribe(
request,
value => {
console.log('onnext');
// obs.next() won't do anything because we ran `obs.return()` which disposes the object
ObservableWrapper.callNext(obs, value);
},
e => {
console.log('onerror');
ObservableWrapper.callThrow(obs, e);
},
() => {
console.log('oncomplete');
ObservableWrapper.callReturn(obs);
});
If you wrap onError and onComplete callbacks with setTimeout then they work as expected
proposal
find a better way to notify zone.js than setTimeout or include setTimeout in the other callbacks
summary
EventEmittershould also resolve onError and onComplete asynchronously for both onError and onComplete.problem
On the server, I'm running into a problem EventEmitter because onComplete is called before onNext
should be
current workaround
include
setTimeoutforonErrorandonCompletebackground/why
as far as I know,
setTimeoutwas added in order for zone.js to pick up any changes. The problem is thatonCompleteresolves first without this change sinceonNextis push to the event loop. If you have any dispose logic in theonCompletecallback then whatever obj you're working with may not work during theonNextcallback. For exampleIf you wrap
onErrorandonCompletecallbacks withsetTimeoutthen they work as expectedproposal
find a better way to notify zone.js than
setTimeoutor includesetTimeoutin the other callbacks