public static <T> AsyncSubject<T> create() { final SubjectSubscriptionManager<T> subscriptionManager = new SubjectSubscriptionManager<T>(); final AtomicReference<Notification<T>> lastNotification = new AtomicReference<Notification<T>>(Notification.<T>createOnCompleted()); OnSubscribe<T> onSubscribe = subscriptionManager.getOnSubscribeFunc( /** * This function executes at beginning of subscription. * * <p>This will always run, even if Subject is in terminal state. */ new Action1<SubjectObserver<? super T>>() { @Override public void call(SubjectObserver<? super T> o) { // nothing to do if not terminated } }, /** This function executes if the Subject is terminated. */ new Action1<SubjectObserver<? super T>>() { @Override public void call(SubjectObserver<? super T> o) { // we want the last value + completed so add this extra logic // to send onCompleted if the last value is an onNext emitValueToObserver(lastNotification.get(), o); } }, null); return new AsyncSubject<T>(onSubscribe, subscriptionManager, lastNotification); }
@Override public void onCompleted() { Collection<SubjectObserver<? super T>> observers = subscriptionManager.terminate( new Action0() { @Override public void call() {} }); if (observers != null) { for (Observer<? super T> o : observers) { emitValueToObserver(lastNotification.get(), o); } } }
@Override public void onError(final Throwable e) { Collection<SubjectObserver<? super T>> observers = subscriptionManager.terminate( new Action0() { @Override public void call() { lastNotification.set(Notification.<T>createOnError(e)); } }); if (observers != null) { for (Observer<? super T> o : observers) { emitValueToObserver(lastNotification.get(), o); } } }