Observable.forkJoin() 不执行
Observable.forkJoin() doesn't execute
我有以下代码:
//Loop: For each user ID/Role ID, get the data
userMeta.forEach((businessRole) => {
Observable.forkJoin(
af.database.object('/roles/'+businessRole.$value),
af.database.object('/users/'+businessRole.$key)
).subscribe(
data => {
console.log("Data received");
data[1].role = data[0];
this.users.push(data[1]);
},
err => console.error(err)
);
我正在尝试使用 forkJoin
订阅 2 个可观察对象的结果。
由于某些原因,"Data received" 消息未显示。
我的 userMeta
变量看起来不错 console.log:
怎么了?
更新:下面的代码也没有return任何东西
let source = Observable.forkJoin(
af.database.object('/roles/'+businessRole.$value),
af.database.object('/users/'+businessRole.$key)
);
let subscription = source.subscribe(
function (x) {
console.log("GOT: " + x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
我实际上想做的是提高以下代码的性能:
//Subscription 3: role ID to role Name
af.database.object('/roles/'+businessRole.$value)
.subscribe((roleData) => {
//Subscription 4: Get user info
af.database.object('/users/'+businessRole.$key).subscribe(user => {
forkJoin()
要求所有源 Observable 至少发出一次并完成。
以下演示按预期完成:
const source = forkJoin(
from([1,2,3]),
from([9,8,7,6])
).subscribe(
x => console.log('GOT:', x),
err => console.log('Error:', err),
() => console.log('Completed')
);
现场演示:https://stackblitz.com/edit/rxjs-urhkni
GOT: 3,6
Completed
2019 年 1 月:针对 RxJS 6 更新
我在使用 Angular 2 / Angularfire 2 时遇到了类似的问题,特别是在我通过电子邮件查找用户是否存在的地方。在一种情况下,用户存在并且我从 Observable 接收到一个包含一个对象的数组。在另一种情况下,用户不存在,我收到一个空数组。
当我将 forkJoin 与 resultSelector 和订阅一起使用时,resultSelector 和订阅函数都没有 运行。然而,当我尝试
Observable.zip(
FirebaseListObservable,
FirebaseListObservable,
(...results) => {
return results.map(some code here)
}
).subscribe(res => console.log(res));
选择器和订阅都有效。我认为这与@martin 的回答有关,其中 forkJoin 需要 observables 完成,因为根据定义它 returns 最后 排放。如果 observable 永远不会完成,我想它永远不会有 last 发射。
也许 angularfire list observables(或您的情况下的 object observables)永远不会完成,从而无法使用 forkJoin。幸运的是 zip 具有 相似 行为并且仍然有效,不同之处在于如果 Firebase 中的数据发生变化,它可以重复多次,而 forkJoin 仅合并最后一个响应。
在我的例子中,我正在查看 1) 使用 zip 并接受如果用户数据发生变化而 .zip 仍然是 运行,我的代码可能会 运行 多次,2 ) 在第一组数据 returns 之后手动禁用 zip,或者 3) 放弃 Angularfire 并直接尝试 Firebase api,使用类似 .once 的东西看看我是否可以得到完成并触发 forkJoin 的可观察对象。
我遇到过类似的问题:我正在动态创建一个可观察对象列表,我注意到如果可观察对象列表为空,forkjoin()
就不会发出也不会完成,而 Promise.all()
会解析有一个空列表:
Observable.forkJoin([])
.subscribe(() => console.log('do something here')); // This is never called
我找到的解决方法是检查列表的长度,当列表为空时不使用此运算符。
return jobList.length ? Observable.forkJoin(jobList) : Observable.of([]);
只需添加 observer.complete();
将不起作用:
observer.next(...)
有效:
observer.next(...);
observer.complete();
希望对您有所帮助。
我遇到了同样的问题,我无法真正让 forkJoin
运算符工作,所以我只使用了 combineLatest
,它已经起作用了!
我有以下代码:
//Loop: For each user ID/Role ID, get the data
userMeta.forEach((businessRole) => {
Observable.forkJoin(
af.database.object('/roles/'+businessRole.$value),
af.database.object('/users/'+businessRole.$key)
).subscribe(
data => {
console.log("Data received");
data[1].role = data[0];
this.users.push(data[1]);
},
err => console.error(err)
);
我正在尝试使用 forkJoin
订阅 2 个可观察对象的结果。
由于某些原因,"Data received" 消息未显示。
我的 userMeta
变量看起来不错 console.log:
怎么了?
更新:下面的代码也没有return任何东西
let source = Observable.forkJoin(
af.database.object('/roles/'+businessRole.$value),
af.database.object('/users/'+businessRole.$key)
);
let subscription = source.subscribe(
function (x) {
console.log("GOT: " + x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
我实际上想做的是提高以下代码的性能:
//Subscription 3: role ID to role Name
af.database.object('/roles/'+businessRole.$value)
.subscribe((roleData) => {
//Subscription 4: Get user info
af.database.object('/users/'+businessRole.$key).subscribe(user => {
forkJoin()
要求所有源 Observable 至少发出一次并完成。
以下演示按预期完成:
const source = forkJoin(
from([1,2,3]),
from([9,8,7,6])
).subscribe(
x => console.log('GOT:', x),
err => console.log('Error:', err),
() => console.log('Completed')
);
现场演示:https://stackblitz.com/edit/rxjs-urhkni
GOT: 3,6
Completed
2019 年 1 月:针对 RxJS 6 更新
我在使用 Angular 2 / Angularfire 2 时遇到了类似的问题,特别是在我通过电子邮件查找用户是否存在的地方。在一种情况下,用户存在并且我从 Observable 接收到一个包含一个对象的数组。在另一种情况下,用户不存在,我收到一个空数组。
当我将 forkJoin 与 resultSelector 和订阅一起使用时,resultSelector 和订阅函数都没有 运行。然而,当我尝试
Observable.zip(
FirebaseListObservable,
FirebaseListObservable,
(...results) => {
return results.map(some code here)
}
).subscribe(res => console.log(res));
选择器和订阅都有效。我认为这与@martin 的回答有关,其中 forkJoin 需要 observables 完成,因为根据定义它 returns 最后 排放。如果 observable 永远不会完成,我想它永远不会有 last 发射。
也许 angularfire list observables(或您的情况下的 object observables)永远不会完成,从而无法使用 forkJoin。幸运的是 zip 具有 相似 行为并且仍然有效,不同之处在于如果 Firebase 中的数据发生变化,它可以重复多次,而 forkJoin 仅合并最后一个响应。
在我的例子中,我正在查看 1) 使用 zip 并接受如果用户数据发生变化而 .zip 仍然是 运行,我的代码可能会 运行 多次,2 ) 在第一组数据 returns 之后手动禁用 zip,或者 3) 放弃 Angularfire 并直接尝试 Firebase api,使用类似 .once 的东西看看我是否可以得到完成并触发 forkJoin 的可观察对象。
我遇到过类似的问题:我正在动态创建一个可观察对象列表,我注意到如果可观察对象列表为空,forkjoin()
就不会发出也不会完成,而 Promise.all()
会解析有一个空列表:
Observable.forkJoin([])
.subscribe(() => console.log('do something here')); // This is never called
我找到的解决方法是检查列表的长度,当列表为空时不使用此运算符。
return jobList.length ? Observable.forkJoin(jobList) : Observable.of([]);
只需添加 observer.complete();
将不起作用:
observer.next(...)
有效:
observer.next(...);
observer.complete();
希望对您有所帮助。
我遇到了同样的问题,我无法真正让 forkJoin
运算符工作,所以我只使用了 combineLatest
,它已经起作用了!