Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AsyncSubject #850

Closed
mattpodwysocki opened this issue Dec 1, 2015 · 9 comments
Closed

Add AsyncSubject #850

mattpodwysocki opened this issue Dec 1, 2015 · 9 comments

Comments

@mattpodwysocki
Copy link
Collaborator

Add AsyncSubject to RxJS v5. Other subjects can be added in the future, but this one is tried and true and used by many community members.

@mattpodwysocki
Copy link
Collaborator Author

@Blesh @staltz correct me if I'm wrong, but wouldn't it be as simple as this?

import {Subject} from '../Subject';
import {Subscriber} from '../Subscriber';
import {Subscription} from '../Subscription';

export class AsyncSubject<T> extends Subject<T> {
  _value: T = void 0;
  _hasNext: boolean = false;
  _isScalar: boolean = true;

  constructor () {
    super();
  }

  _subscribe(subscriber: Subscriber<any>): Subscription<T> {
    const subscription = super._subscribe(subscriber);
    if (!subscription) {
      return;
    } else if (!subscription.isUnsubscribed && this._hasNext) {
      subscriber.next(this._value);
      subscriber.complete();
    }
    return subscription;
  }

  _next(value: T): void {
    this._value = value;
    this._hasNext = true;
  }

  _complete(): void {
    let index = -1;
    const observers = this.observers;
    const len = observers.length;

    // optimization -- block next, complete, and unsubscribe while dispatching
    this.observers = void 0; // optimization
    this.isUnsubscribed = true;

    if (this._hasNext) {
      while (++index < len) {
        observers[index].next(this._value);
        observers[index].complete();
      }
    } else {
      while (++index < len) {
        observers[index].complete();
      }
    }

    this.isUnsubscribed = false;
  }
}

@benlesh
Copy link
Member

benlesh commented Dec 1, 2015

LGTM.

I think once this completes, you could set _isScalar to true on it and get some benefits from operators that fast-track scalar observables.

@benlesh
Copy link
Member

benlesh commented Dec 1, 2015

minor thing would be to put observers[index] in a variable inside of that first loop, just to avoid the lookup twice. I'm unsure about the micro-optimization, but it would probably minify cleaner.

@benlesh
Copy link
Member

benlesh commented Dec 1, 2015

... also, you'd want to default _isScalar to false until it completes, and hasValue, then set it to true. That way when used after that by operators that have optimizations for scalar observables, it should just pull the value out of value directly.

@antoineol
Copy link

👍 for AsyncSubject, thanks!

Just one question: what would be the difference with new ReplaySubject(1) (if any)? I just learnt about this alternative from angular2 gitter.

@staltz
Copy link
Member

staltz commented Dec 2, 2015

@architruc very different. AsyncSubject does not emit next values before it completes. It only emits on completion, and after completion for late subscribers.

@antoineol
Copy link

@staltz Okay, if I understand well ReplaySubject emits at each value (let's say each next() in the source), but AsyncSubject on complete() in the source, right?

Yes, it is different, seems I misunderstood, although AsyncSubject could still help in my usecase. Thanks!

@benlesh
Copy link
Member

benlesh commented Dec 5, 2015

This can be closed now, I think.

@benlesh benlesh closed this as completed Dec 5, 2015
@lock
Copy link

lock bot commented Jun 7, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants