将有序操作列表合并到一个Observable中

时间:2016-10-24 21:58:18

标签: javascript promise rxjs observable rxjs5

var state = [];
var operation1 = function() {
    return Rx.Observable.fromPromise(new Promise((resolve, reject) => {
        state.push(1, 2);
        setTimeout(resolve, 300, state);
    }));
};
var operation2 = function() {
    return Rx.Observable.fromPromise(new Promise((resolve, reject) => {
        state = state.map(x => x * 2);
        setTimeout(resolve, 200, state);
    }));
};
var operation3 = function() {
    return Rx.Observable.fromPromise(new Promise((resolve, reject) => {
        state = state.reduce( (prev, next) => prev + next );
        setTimeout(resolve, 100, state);
    }));
};
var operations = [operation1, operation2, operation3];

鉴于上面的代码,我试图将operations合并到一个发出每个操作状态的Observable中。因此Observable需要执行以下任一操作:

  • 发出3次:[1, 2], [2, 4], 6
  • 发出1次:[[1, 2], [2, 4], 6]

2 个答案:

答案 0 :(得分:3)

您可以尝试(jsbin

var state = [];
var operation1 = Rx.Observable.defer(function() {
    return Rx.Observable.fromPromise(new Promise((resolve, reject) => {
        state.push(1, 2);
        setTimeout(resolve, 300, state);
    }));
});
var operation2 = Rx.Observable.defer(function() {
    return Rx.Observable.fromPromise(new Promise((resolve, reject) => {
        state = state.map(x => x * 2);
        setTimeout(resolve, 200, state);
    }));
});
var operation3 = Rx.Observable.defer(function() {
    return Rx.Observable.fromPromise(new Promise((resolve, reject) => {
        state = state.reduce( (prev, next) => prev + next );
        setTimeout(resolve, 100, state);
    }));
});
var operations = Rx.Observable.from([operation1, operation2, operation3]).merge(1);
operations.subscribe(function(x){console.log(x)})

请检查是否有诀窍,稍后我会详细说明其工作原理。

答案 1 :(得分:0)

您可以使用Rx.Observable.concat,但我认为如果没有rx.java并使用Promise.all

,这个简单的情况会更容易

let slow = new Promise((resolve) => {
  setTimeout(resolve, 200, 'slow');
});
let instant = new Promise((resolve) => {
  setTimeout(resolve, 0, 'instant');
});
let quick = new Promise((resolve) => {
  setTimeout(resolve, 50, 'quick');
});

var operation1 = function() {
  return Rx.Observable.fromPromise(slow);
}
var operation2 = function() {
  return Rx.Observable.fromPromise(instant);
}
var operation3 = function() {
  return Rx.Observable.fromPromise(quick);
}
var operations = [operation1(), operation2(), operation3()];
var source = Rx.Observable.concat(operations);

var subscription = source.subscribe(
  function(x) {
    console.log('Next: ' + x);
  },
  function(err) {
    console.log('Error: ' + err);
  },
  function(a) {
    console.log('Completed', a);
  });

// Or with promises

operations = [slow, instant, quick]

Promise.all(operations)
.then(console.log.bind(console, "Promise all"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.min.js"></script>