从 2 个 observables 获取一次数据
Get data once from 2 observables
我有2个observable,每个observable我只需要获取一次。
我做的是订阅中的订阅,尽管它们可以同时(并行)执行。
let table = this.af.database.object('tables');
table.subscribe((tableData) => {
let section_seats = this.af.database.object('sections').take(1)
.subscribe((sectionData) => {
//Here I'm Using tableData & sectionData
});
});
上面的代码很好用,但是虽然可以,但它们并没有同时执行。
如何同时执行两个可观察对象然后使用从它们接收到的数据?
更新:使用 forkJoin() 什么也不做(以下代码没有控制台日志)
var source = Observable.forkJoin(
this.af.database.object('tables'),
this.af.database.object('sections')
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
您应该使用 withLatestFrom
运算符。
上查看更多信息
/* Have staggering intervals */
var source1 = Rx.Observable.interval(140)
.map(function (i) { return 'First: ' + i; });
var source2 = Rx.Observable.interval(50)
.map(function (i) { return 'Second: ' + i; });
// When source1 emits a value, combine it with the latest emission from source2.
var source = source1.withLatestFrom(
source2,
function (s1, s2) { return s1 + ', ' + s2; }
).take(4);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: First: 0, Second: 1
// => Next: First: 1, Second: 4
// => Next: First: 2, Second: 7
// => Next: First: 3, Second: 10
// => Completed
forJoin
的文档对其进行了解释:
Runs all observable sequences in parallel and collect their last elements.
我认为 last 元素将是在 observable 完成之前触发的最后一个元素,因此您传递给 forkJoin
的所有 Observables 必须在任何事情完成之前完成发射。
因为你只想要第一个发出的元素,所以尝试让每个 Observable 在它第一次发出后完成:
var source = Observable.forkJoin(
this.af.database.object('tables').take(1),
this.af.database.object('sections').take(1)
);
有多种方法(阅读、运算符)可以帮助您合并资源。在 Combining multiple observable sequences into a single sequence
部分中可以找到一般资源 here。对于您的具体问题,以下是似乎符合要求的短名单:
- combineLatest:当 1. 两个源都至少发出一个值时发出一个值,2. 之后,任何时候其中一个源发出一个值。
例如:Rx.Observable.combineLatest(object('tables'), object('sections').take(1))
- withLatestFrom : 当第一个源发出一个值时发出一个值。发射值包括第二个来源的最新发射值。
例如:object('tables').withLatesFrom(object('sections').take(1))
- zip :当两个源都发出一个值时发出第一个值。通过相同的过程发出第 N 个值。
例如:Rx.Observable.zip(object('tables'), object('sections').take(1))
这些运算符中的每一个都有相似但略有不同的语义。我会假设 combineLatest
是您需要的,但请检查文档,设置一些代码并尝试一些东西,如果这不起作用,请返回并在此处 post 它。
试试这个:
var source = Observable.forkJoin(
this.af.database.object('tables'),
this.af.database.object('sections')
);
var subscription = source.subscribe(
data => {
console.log(data[0]);
console.log(data[1]);
},
err => console.error(err)
);
我有2个observable,每个observable我只需要获取一次。
我做的是订阅中的订阅,尽管它们可以同时(并行)执行。
let table = this.af.database.object('tables');
table.subscribe((tableData) => {
let section_seats = this.af.database.object('sections').take(1)
.subscribe((sectionData) => {
//Here I'm Using tableData & sectionData
});
});
上面的代码很好用,但是虽然可以,但它们并没有同时执行。
如何同时执行两个可观察对象然后使用从它们接收到的数据?
更新:使用 forkJoin() 什么也不做(以下代码没有控制台日志)
var source = Observable.forkJoin(
this.af.database.object('tables'),
this.af.database.object('sections')
);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
您应该使用 withLatestFrom
运算符。
/* Have staggering intervals */
var source1 = Rx.Observable.interval(140)
.map(function (i) { return 'First: ' + i; });
var source2 = Rx.Observable.interval(50)
.map(function (i) { return 'Second: ' + i; });
// When source1 emits a value, combine it with the latest emission from source2.
var source = source1.withLatestFrom(
source2,
function (s1, s2) { return s1 + ', ' + s2; }
).take(4);
var subscription = source.subscribe(
function (x) {
console.log('Next: ' + x.toString());
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
// => Next: First: 0, Second: 1
// => Next: First: 1, Second: 4
// => Next: First: 2, Second: 7
// => Next: First: 3, Second: 10
// => Completed
forJoin
的文档对其进行了解释:
Runs all observable sequences in parallel and collect their last elements.
我认为 last 元素将是在 observable 完成之前触发的最后一个元素,因此您传递给 forkJoin
的所有 Observables 必须在任何事情完成之前完成发射。
因为你只想要第一个发出的元素,所以尝试让每个 Observable 在它第一次发出后完成:
var source = Observable.forkJoin(
this.af.database.object('tables').take(1),
this.af.database.object('sections').take(1)
);
有多种方法(阅读、运算符)可以帮助您合并资源。在 Combining multiple observable sequences into a single sequence
部分中可以找到一般资源 here。对于您的具体问题,以下是似乎符合要求的短名单:
- combineLatest:当 1. 两个源都至少发出一个值时发出一个值,2. 之后,任何时候其中一个源发出一个值。
例如:Rx.Observable.combineLatest(object('tables'), object('sections').take(1))
- withLatestFrom : 当第一个源发出一个值时发出一个值。发射值包括第二个来源的最新发射值。
例如:object('tables').withLatesFrom(object('sections').take(1))
- zip :当两个源都发出一个值时发出第一个值。通过相同的过程发出第 N 个值。
例如:Rx.Observable.zip(object('tables'), object('sections').take(1))
这些运算符中的每一个都有相似但略有不同的语义。我会假设 combineLatest
是您需要的,但请检查文档,设置一些代码并尝试一些东西,如果这不起作用,请返回并在此处 post 它。
试试这个:
var source = Observable.forkJoin(
this.af.database.object('tables'),
this.af.database.object('sections')
);
var subscription = source.subscribe(
data => {
console.log(data[0]);
console.log(data[1]);
},
err => console.error(err)
);