避免重复使用异步服务填充数组

时间:2017-03-30 19:04:42

标签: javascript angular asynchronous rxjs rxjs5

我有一个组件从服务中提取内容来处理它。问题是我可以多次调用此函数,这会导致我的数组重复。我有以下解决方法:

    getOptions(): Observable<PickQuality[]> {
    console.log("MY LENGTH: ", this.options.length) // <=== Always returns 0 because the callback hasn't run yet
    if(this.options.length == 0) {
        this.championService.getChampions()
            .subscribe(champions => {
                champions.forEach(champion => this.options.push(new PickQuality(champion, 0)));
                this.reevaluate();
                this.optionsSubject.next(this.options);
            });

        return this.optionsSubject.asObservable();
    }
    else
        return Observable.of(this.options);
}

并且它不起作用,然后我在回调中尝试了以下技巧(正确识别this.options.length):

                    if(this.options.length != 0) return; // <=== Looks bad!

实际上有效,但对我来说似乎效率极低,因为我的服务调用仍然执行。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

我建议稍微重新构建一下代码:

if (this.options.length == 0) {
    let source = this.championService.getChampions()
        .share();

    source.subscribe(champions => {
        // ... whatever
        this.options = whateverResult;
    });

    return source;
} else {
    return Observable.of(this.options);
}

现在您可以避免使用Subjects并返回代表HTTP请求的源Observable,并通过share()运算符共享。这意味着只有一个HTTP请求,其结果将发送到此内部subscribe()调用以及此方法之外的订阅者。

答案 1 :(得分:0)

在推送之前检查重复项。

this.championService.getChampions()
.subscribe(champions => {
    champions.forEach(champion => {
       if (champions.indexOf(champion) == -1)
          this.options.push(new PickQuality(champion, 0));
    });
    this.reevaluate();
    this.optionsSubject.next(this.options);
});