RxJS implements this operator as zip
and zipArray
.
zip
accepts a variable number of Observables or Promises as parameters, followed
by a function that accepts one item emitted by each of those Observables or resolved by those
Promises as input and produces a single item to be emitted by the resulting Observable.
Sample Code
/* Using arguments */
var range = Rx.Observable.range(0, 5);
var source = Observable.zip(
range,
range.skip(1),
range.skip(2),
function (s1, s2, s3) {
return s1 + ':' + s2 + ':' + s3;
}
);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
Next: 0:1:2
Next: 1:2:3
Next: 2:3:4
Completed
/* Using promises and Observables */
var range = Rx.Observable.range(0, 5);
var source = Observable.zip(
RSVP.Promise.resolve(0),
RSVP.Promise.resolve(1),
Rx.Observable.return(2)
function (s1, s2, s3) {
return s1 + ':' + s2 + ':' + s3;
}
);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
zipArray
accepts a variable number of Observables as parameters and returns an
Observable that emits arrays, each one containing the n th item from each
source Observable.
Sample Code
var range = Rx.Observable.range(0, 5);
var source = Rx.Observable.zipArray(
range,
range.skip(1),
range.skip(2)
);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
Next: [0,1,2]
Next: [1,2,3]
Next: [2,3,4]
Completed
RxJS also implements a similar operator, forkJoin
. There are two varieties of this
operator. The first collects the last element emitted by each of the source Observables into an array and
emits this array as its own sole emitted item. You can either pass a list of Observables to
forkJoin
as individual parameters or as an array of Observables.
var source = Rx.Observable.forkJoin(
Rx.Observable.return(42),
Rx.Observable.range(0, 10),
Rx.Observable.fromArray([1,2,3]),
RSVP.Promise.resolve(56)
);
var subscription = source.subscribe(
function (x) { console.log('Next: ' + x); },
function (err) { console.log('Error: ' + err); },
function () { console.log('Completed'); });
Next: [42, 9, 3, 56]
Completed
A second variant of forkJoin
exists as a prototype function, and you call it on an instance
of one source Observable, passing it another source Observable as a parameter. As a second parameter,
you pass it a function that combines the final item emitted by the two source Observables into the sole
item to be emitted by the resulting Observable.
var source1 = Rx.Observable.return(42);
var source2 = Rx.Observable.range(0, 3);
var source = source1.forkJoin(source2, function (s1, s2) {
return s1 + s2;
});
var subscription = source.subscribe(
function (x) { console.log('Next: ' + x); },
function (err) { console.log('Error: ' + err); },
function () { console.log('Completed'); });
forkJoin
is found in the following distributions:
rx.all.js
rx.all.compat.js
rx.experimental.js
(requires rx.js
, rx.compat.js
, rx.lite.js
, or rx.lite.compat.js
)