Skip to content

include setTimeout in EventEmitter onError and onComplete #4443

Closed

Description

@PatrickJS

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

Activity

  1. angular-automatic-lock-bot commented on Sep 7, 2019

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  2. locked and limited conversation to collaborators on Sep 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions