rx.subjects.AsyncSubject Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rxjava-core Show documentation
Show all versions of rxjava-core Show documentation
rxjava-core developed by Netflix
/**
* Copyright 2014 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package rx.subjects;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicReference;
import rx.Notification;
import rx.Observer;
import rx.functions.Action1;
import rx.subjects.SubjectSubscriptionManager.SubjectObserver;
/**
* Subject that publishes only the last event to each {@link Observer} that has subscribed when the
* sequence completes.
*
*
*
* Example usage:
*
*
{@code
*
* // observer will receive no onNext events because the subject.onCompleted() isn't called.
AsyncSubject
*
* @param
*/
public final class AsyncSubject extends Subject {
public static AsyncSubject create() {
final SubjectSubscriptionManager subscriptionManager = new SubjectSubscriptionManager();
final AtomicReference> lastNotification = new AtomicReference>(new Notification());
OnSubscribe onSubscribe = subscriptionManager.getOnSubscribeFunc(
/**
* This function executes at beginning of subscription.
*
* This will always run, even if Subject is in terminal state.
*/
new Action1>() {
@Override
public void call(SubjectObserver super T> o) {
// nothing to do if not terminated
}
},
/**
* This function executes if the Subject is terminated.
*/
new Action1>() {
@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(onSubscribe, subscriptionManager, lastNotification);
}
protected static void emitValueToObserver(Notification n, Observer super T> o) {
n.accept(o);
if (n.isOnNext()) {
o.onCompleted();
}
}
private final SubjectSubscriptionManager subscriptionManager;
final AtomicReference> lastNotification;
protected AsyncSubject(OnSubscribe onSubscribe, SubjectSubscriptionManager subscriptionManager, AtomicReference> lastNotification) {
super(onSubscribe);
this.subscriptionManager = subscriptionManager;
this.lastNotification = lastNotification;
}
@Override
public void onCompleted() {
subscriptionManager.terminate(new Action1>>() {
@Override
public void call(Collection> observers) {
for (Observer super T> o : observers) {
emitValueToObserver(lastNotification.get(), o);
}
}
});
}
@Override
public void onError(final Throwable e) {
subscriptionManager.terminate(new Action1>>() {
@Override
public void call(Collection> observers) {
lastNotification.set(new Notification(e));
for (Observer super T> o : observers) {
emitValueToObserver(lastNotification.get(), o);
}
}
});
}
@Override
public void onNext(T v) {
lastNotification.set(new Notification(v));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy