我开始玩Angular 6和Firebase。我想使用Hacker News API来显示提要(内容)。
我想返回Thing类数组的一个可观察值。首先,我需要一个供稿ID数组,因此我打电话给Firebase来获取它们。然后,我想获取每个已有ID的提要,并将其作为可观察到的提要数组返回。
到目前为止,我的代码是这样的:
class SubTensorBoard(TensorBoard):
def __init__(self, *args, **kwargs):
super(SubTensorBoard, self).__init__(*args, **kwargs)
def lr_getter(self):
# Get vals
decay = self.model.optimizer.decay
lr = self.model.optimizer.lr
iters = self.model.optimizer.iterations # only this should not be const
beta_1 = self.model.optimizer.beta_1
beta_2 = self.model.optimizer.beta_2
# calculate
lr = lr * (1. / (1. + decay * K.cast(iters, K.dtype(decay))))
t = K.cast(iters, K.floatx()) + 1
lr_t = lr * (K.sqrt(1. - K.pow(beta_2, t)) / (1. - K.pow(beta_1, t)))
return np.float32(K.eval(lr_t))
def on_epoch_end(self, episode, logs = {}):
logs.update({"lr": self.lr_getter()})
super(SubTensorBoard, self).on_epoch_end(episode, logs)
我认为可以使用数组中的flatMapping解决方案,但是我得到了getThings(limit: number): Observable<any> {
return this.db.list('/v0/beststories', ref => ref.limitToFirst(limit).orderByKey())
.valueChanges() // returns an Observable of IDs
.pipe(
flatMap(itemIds => {
if (itemIds.length > 0) {
let sources = itemIds.map(itemId => defer(() => {
let pathOrRef = '/v0/item/' + itemId;
return this.db.object(pathOrRef).valueChanges();
}));
// sources are the array of Observables
return forkJoin(sources);
} else {
return Observable.create([]);
}
})
);
}
。
我尝试以与RxJs Array of Observable to Array中类似的方式执行此操作,但是我不知道自己在哪里犯了错误。
调用返回的Observable上的订阅后引发错误:
You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable
我在以下代码段中再现了类似的情况:https://stackblitz.com/edit/angular-8qtokd?file=src%2Fapp%2Fapp.component.ts
答案 0 :(得分:4)
尝试使用switchMap
和combineLatest
。例如
import {combineLatest, Observable} from 'rxjs';
import {map, switchMap} from 'rxjs/operators';
function getThings(limit: number): Observable<any> {
return this.db.list('/v0/beststories', ref => ref.limitToFirst(limit).orderByKey())
.valueChanges() // returns an Observable of IDs
.pipe(
switchMap(itemIds => {
if (itemIds.length > 0) {
let sources = itemIds.map(itemId => {
let pathOrRef = '/v0/item/' + itemId;
return this.db.object(pathOrRef).valueChanges();
});
// sources are the array of Observables
return combineLatest(sources);
} else {
return Observable.create([]);
}
})
);
}
答案 1 :(得分:0)