如何从可观察对象数组中返回可观察对象

时间:2018-07-08 11:46:46

标签: angular typescript firebase-realtime-database

我开始玩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

2 个答案:

答案 0 :(得分:4)

尝试使用switchMapcombineLatest。例如

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)

enter image description here

在对带有两个方括号的矩形进行编码时,效果很好:

<body>
    <div class="grid">
        <div class="left">
            <div class="one">1</div>
            <div class="two">2</div>
            <div class="three">3</div>
        </div>
        <div class="right">
            <div class="four">4</div>
            <div class="five">5</div>
            <div class="six">6</div>
            <div class="seven">7</div>
        </div>
    </div>
</body>