私はこれを理解しようとしてこれに頭を突っ込んでおり、私が読むことができたドキュメントの量は私の質問への答えを与えてくれませんでした。
APIに直接話し、観察可能なイベントを返すサービスがあり、通常の状況では、データに登録して必要な処理を行いますが、残りのサービスからのリクエストを利用するセカンダリサービスでは、リクエストから値を返すことができます。
_getSomething() {
return this._restService.addRequest('object', 'method').run()
.subscribe(
res => {
res;
},
err => {
console.error(err);
}
);
}
returnSomething() {
return this.getSomething();
}
_
上記の簡単な例では、getSomething()
内でreturnSomething()
からres
を返す方法があるかどうかを知りたいと思います。この方法で達成できない場合、代替手段は何ですか? _restServiceは非常に大きく依存しているので、それをいじり始めたくないと付け加えます。
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);
});
私は自分でこれを使用しませんでしたが、理論的には機能するはずだと思います(:
// 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 ...
同様の問題がありました。私の解決策は、.toPromise()でobservableをpromiseに変換することでした(async-awaitを使用してそれを返し、エラーをキャッチします)。コードを次のようなものに変換できます。
async getSomething() {
try{
return await this._restService.addRequest('object', 'method').run().toPromise()
} catch (err){
console.error(err);
}
}