web-dev-qa-db-ja.com

Angular 2-Observableから直接データを返す

私はこれを理解しようとしてこれに頭を突っ込んでおり、私が読むことができたドキュメントの量は私の質問への答えを与えてくれませんでした。

APIに直接話し、観察可能なイベントを返すサービスがあり、通常の状況では、データに登録して必要な処理を行いますが、残りのサービスからのリクエストを利用するセカンダリサービスでは、リクエストから値を返すことができます。

_getSomething() {
    return this._restService.addRequest('object', 'method').run()
        .subscribe(
            res => {
                res;
            },
            err => {
                console.error(err);
            }
        );
}

returnSomething() {
    return this.getSomething();
}
_

上記の簡単な例では、getSomething()内でreturnSomething()からresを返す方法があるかどうかを知りたいと思います。この方法で達成できない場合、代替手段は何ですか? _restServiceは非常に大きく依存しているので、それをいじり始めたくないと付け加えます。

29
Sidriel

Http呼び出しなどは非同期であるため、返される同期値の代わりにObservableを取得します。購読する必要があり、そこのコールバックでデータを取得します。それを回避する方法はありません。

1つのオプションは、subscribe呼び出しにロジックを配置することです

getSomething() {
    return this._restService.addRequest('object', 'method').run()
        .subscribe(
            res => {
                // do something here
                res;
            },
            err => {
                console.error(err);
            }
        );
}

しかし、私がそれを行うのが好きな方法は、コールバックを追加し、外部からロジックを注入することです(おそらくコンポーネント、別のサービスかもしれません):

getSomething(callback: (data) => void) {
    return this._restService.addRequest('object', 'method').run()
        .subscribe(
            res => {
                callback(res);
            },
            err => {
                console.error(err);
            }
        );
}

そして、コンポーネント内またはどこでも:

this._yourService.getSomething((data) => {
    // do something here
    console.log(data);
});
42
rinukkusu

私は自分でこれを使用しませんでしたが、理論的には機能するはずだと思います(:

// service.ts
getSomething() {
  let subject: Subject = new Subject();
  this._restService.addRequest('object', 'method').run()
    .subscribe(subject);
  return subject;
}

// this can be removed (;
returnSomething() {
  return this.getSomething();
}

// component.ts
ngOnInit() {
  this.service.returnSomething()
    .subscribe(res => console.log(res), err => console.log(err));
}

詳細については、 subject docs を確認してください。さまざまな種類のサブジェクトを使用できます。たとえば、BehaviorSubjectには、アクセス可能なvalueプロパティがあります...

ngOnInit() {
  // if you use BehaviorSubject
  this.service.returnSomething().value
}

working plunker ...

1
Sasxa

同様の問題がありました。私の解決策は、.toPromise()でobservableをpromiseに変換することでした(async-awaitを使用してそれを返し、エラーをキャッチします)。コードを次のようなものに変換できます。

 async getSomething() {
     try{
         return await this._restService.addRequest('object', 'method').run().toPromise()
      } catch (err){
       console.error(err);
          }
  }
0
hjbello