Skip to content

Zip calls onNext later than C#'s Zip does #387

@samuelgruetter

Description

@samuelgruetter

In the C# example below, the zipped Observable completes as soon as o3 has completed, because all of o3's elements have been paired with an element from o6.

static void Main() {
    var o3 = Observable.Interval(TimeSpan.FromMilliseconds(1000)).Take(3);
    var o6 = Observable.Interval(TimeSpan.FromMilliseconds(1000)).Take(10);

    var watch = new Stopwatch();
    watch.Start();

    Observable.Zip(o3, o6).Subscribe(
        list => Console.WriteLine("(" + list[0] + ", " + list[1] + ") at t=" + watch.ElapsedMilliseconds), 
        e => Console.WriteLine(e.StackTrace),
        () => Console.WriteLine("complete at t=" + watch.ElapsedMilliseconds)
    );
    Console.ReadLine();
}

outputs

(0, 0) at t=1055
(1, 1) at t=2045
(2, 2) at t=3047
complete at t=4058

In the corresponding Java code, however, the zipped Observable only completes once both o3 and o6 have completed.

static Func2<Long, Long, Long> zipFunc = new Func2<Long, Long, Long>() {
    public Long call(Long n1, Long n2) {
        if (n1.equals(n2)) {
            return n1;
        } else {
            throw new RuntimeException("numbers not equal");
        }
    }
};

public static void main(String[] args) {
    Observable<Long> o3 = Observable.interval(1000, TimeUnit.MILLISECONDS).take(3);
    Observable<Long> o6 = Observable.interval(1000, TimeUnit.MILLISECONDS).take(10);

    final long startTime = System.currentTimeMillis();

    Observable.zip(o3, o6, zipFunc).subscribe(
        new Action1<Long>() { public void call(Long n) { 
            System.out.println(n + " at t=" + (System.currentTimeMillis()-startTime));
        }},
        new Action1<Throwable>() { public void call(Throwable t) {
            t.printStackTrace();
        }},
        new Action0() { public void call() {
            System.out.println("complete at t=" + (System.currentTimeMillis()-startTime));
        }}
    );
}

outputs

0 at t=1019
1 at t=2019
2 at t=3019
complete at t=10019

I'd like RxJava to follow C# here, unless there are very good reasons against doing so.

This difference becomes even more important if one of the observables never completes: Then, the zipped Observable never completes either, which was very unexpected for me.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions