diff --git a/packages/core/src/event_emitter.ts b/packages/core/src/event_emitter.ts index b7a2bd2217..3136af5f9e 100644 --- a/packages/core/src/event_emitter.ts +++ b/packages/core/src/event_emitter.ts @@ -8,7 +8,7 @@ /// -import {Subject, Subscription} from 'rxjs'; +import {PartialObserver, Subject, Subscription} from 'rxjs'; /** * Use in components with the `@Output` directive to emit custom events @@ -115,57 +115,30 @@ class EventEmitter_ extends Subject { } subscribe(observerOrNext?: any, error?: any, complete?: any): Subscription { - let schedulerFn: (t: any) => any; - let errorFn = (err: any): any => null; - let completeFn = (): any => null; + let nextFn = observerOrNext; + let errorFn = error || (() => null); + let completeFn = complete; if (observerOrNext && typeof observerOrNext === 'object') { - schedulerFn = this.__isAsync ? (value: any) => { - setTimeout(() => observerOrNext.next(value)); - } : (value: any) => { - observerOrNext.next(value); - }; + const observer = observerOrNext as PartialObserver; + nextFn = observer.next?.bind(observer); + errorFn = observer.error?.bind(observer); + completeFn = observer.complete?.bind(observer); + } - if (observerOrNext.error) { - errorFn = this.__isAsync ? (err) => { - setTimeout(() => observerOrNext.error(err)); - } : (err) => { - observerOrNext.error(err); - }; + if (this.__isAsync) { + errorFn = _wrapInTimeout(errorFn); + + if (nextFn) { + nextFn = _wrapInTimeout(nextFn); } - if (observerOrNext.complete) { - completeFn = this.__isAsync ? () => { - setTimeout(() => observerOrNext.complete()); - } : () => { - observerOrNext.complete(); - }; - } - } else { - schedulerFn = this.__isAsync ? (value: any) => { - setTimeout(() => observerOrNext(value)); - } : (value: any) => { - observerOrNext(value); - }; - - if (error) { - errorFn = this.__isAsync ? (err) => { - setTimeout(() => error(err)); - } : (err) => { - error(err); - }; - } - - if (complete) { - completeFn = this.__isAsync ? () => { - setTimeout(() => complete()); - } : () => { - complete(); - }; + if (completeFn) { + completeFn = _wrapInTimeout(completeFn); } } - const sink = super.subscribe(schedulerFn, errorFn, completeFn); + const sink = super.subscribe({next: nextFn, error: errorFn, complete: completeFn}); if (observerOrNext instanceof Subscription) { observerOrNext.add(sink); @@ -175,6 +148,12 @@ class EventEmitter_ extends Subject { } } +function _wrapInTimeout(fn: (value: unknown) => any) { + return (value: unknown) => { + setTimeout(fn, undefined, value); + }; +} + /** * @publicApi */ diff --git a/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json b/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json index 25a9a2ee4e..07bd65c2d5 100644 --- a/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json +++ b/packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json @@ -650,6 +650,9 @@ { "name": "_testabilityGetter" }, + { + "name": "_wrapInTimeout" + }, { "name": "addComponentLogic" }, diff --git a/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json b/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json index b725159dd1..a5bc8195ca 100644 --- a/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json +++ b/packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json @@ -638,6 +638,9 @@ { "name": "_testabilityGetter" }, + { + "name": "_wrapInTimeout" + }, { "name": "addComponentLogic" }, diff --git a/packages/core/test/bundling/router/bundle.golden_symbols.json b/packages/core/test/bundling/router/bundle.golden_symbols.json index ef5302071d..94c93decc9 100644 --- a/packages/core/test/bundling/router/bundle.golden_symbols.json +++ b/packages/core/test/bundling/router/bundle.golden_symbols.json @@ -926,6 +926,9 @@ { "name": "_testabilityGetter" }, + { + "name": "_wrapInTimeout" + }, { "name": "absoluteRedirect" },