ForEach 比我的 Observable returns 值更快
ForEach is faster than my Observable returns values
我有以下代码:
evaluateLocations() {
const locs = this.currentTour.locIds;
let lastLoc = null;
locs.forEach(loc => {
console.log(lastLoc, loc);
if (lastLoc !== null) {
console.log('if durch', lastLoc, loc);
this.afDb.list('routes', {
query: {
orderByChild: 'idStart',
equalTo: loc
}
}).switchMap(items => {
console.log('switchMap starts', lastLoc, loc); //here the output is always lastLoc = loc while it shouldn't be that
const filtered = items.filter(item => item.idEnd === lastLoc);
const route = filtered[0];
return Observable.of(route);
}).subscribe();
}
lastLoc = loc;
});
}
现在,在 switchMap
开始发挥作用时,forEach
循环似乎已经 运行 通过,所以过滤总是错误的。
我的逻辑是:
我想遍历一个 id 数组。然后我调用数据库获取起点为 locs[n]
的所有条目。然后我想过滤 locs[n+1]
,它会 return 一个结果。
理论上这应该可行,但考虑到我从 Firebase
数据库查询,Observable 在那里有时间滞后,我无法足够快地获取值。我怀疑和我读到的另一件事是,如果在当前完成之前启动另一个,则 Observables
可能会被取消。但是当我 运行 我的代码时,这似乎不是问题。
如果要按顺序处理该列表,则需要等待 Observable
的操作完成。一种惯用的方法 seems to be 将 Observable
转换为 Promise
和 await
即:
将其应用于您的代码:
async evaluateLocations() { // <-- make method async, so we can use await
const locs = this.currentTour.locIds;
let lastLoc = null;
for (let locKey in locs) { // <-- use regular for-in loop
let loc = locs[locKey];
console.log(lastLoc, loc);
if (lastLoc !== null) {
console.log('if durch', lastLoc, loc);
await this.afDb.list('routes', { // <-- use await here
query: {
orderByChild: 'idStart',
equalTo: loc
}
}).switchMap(items => {
console.log('switchMap starts', lastLoc, loc); //here the output is always lastLoc = loc while it shouldn't be that
const filtered = items.filter(item => item.idEnd === lastLoc);
const route = filtered[0];
return Observable.of(route);
}).toPromise(); // <-- convert to Promise
}
lastLoc = loc;
}
}
不要忘记,如果您之后需要做一些依赖于 evaluateLocations()
.
的结果,您现在也需要在调用函数中等待 evaluateLocations()
我有以下代码:
evaluateLocations() {
const locs = this.currentTour.locIds;
let lastLoc = null;
locs.forEach(loc => {
console.log(lastLoc, loc);
if (lastLoc !== null) {
console.log('if durch', lastLoc, loc);
this.afDb.list('routes', {
query: {
orderByChild: 'idStart',
equalTo: loc
}
}).switchMap(items => {
console.log('switchMap starts', lastLoc, loc); //here the output is always lastLoc = loc while it shouldn't be that
const filtered = items.filter(item => item.idEnd === lastLoc);
const route = filtered[0];
return Observable.of(route);
}).subscribe();
}
lastLoc = loc;
});
}
现在,在 switchMap
开始发挥作用时,forEach
循环似乎已经 运行 通过,所以过滤总是错误的。
我的逻辑是:
我想遍历一个 id 数组。然后我调用数据库获取起点为 locs[n]
的所有条目。然后我想过滤 locs[n+1]
,它会 return 一个结果。
理论上这应该可行,但考虑到我从 Firebase
数据库查询,Observable 在那里有时间滞后,我无法足够快地获取值。我怀疑和我读到的另一件事是,如果在当前完成之前启动另一个,则 Observables
可能会被取消。但是当我 运行 我的代码时,这似乎不是问题。
如果要按顺序处理该列表,则需要等待 Observable
的操作完成。一种惯用的方法 seems to be 将 Observable
转换为 Promise
和 await
即:
将其应用于您的代码:
async evaluateLocations() { // <-- make method async, so we can use await
const locs = this.currentTour.locIds;
let lastLoc = null;
for (let locKey in locs) { // <-- use regular for-in loop
let loc = locs[locKey];
console.log(lastLoc, loc);
if (lastLoc !== null) {
console.log('if durch', lastLoc, loc);
await this.afDb.list('routes', { // <-- use await here
query: {
orderByChild: 'idStart',
equalTo: loc
}
}).switchMap(items => {
console.log('switchMap starts', lastLoc, loc); //here the output is always lastLoc = loc while it shouldn't be that
const filtered = items.filter(item => item.idEnd === lastLoc);
const route = filtered[0];
return Observable.of(route);
}).toPromise(); // <-- convert to Promise
}
lastLoc = loc;
}
}
不要忘记,如果您之后需要做一些依赖于 evaluateLocations()
.
evaluateLocations()