私はRxJにかなり慣れていないので、RxをPromisesと組み合わせて使用するのが最善の方法を理解したいと思います。
私が作成したいのは、Angularのサービスで、イベントディスパッチャーパターンとして機能し、promiseが完了するとイベントを発行します。また、必要なのは、(event )オブザーバブルのサブスクライバーが呼び出されることはありません。最後に、オブザーバブルの後続のサブスクライバーは、サーバーへの別の要求をトリガーせずに同じ結果を取得します。ここで独自のソリューションを実装できました。
// ... CountryService code
var COUNTRIES_LOADED = Rx.Observable
.create(function (observer) {
$http
.get('/countries')
.then(function (res) {
observer.onNext(res);
}, function (err) {
observer.onError(err);
})
.finally(function () {
observer.onCompleted();
});
})
.shareReplay();
これで、新しい「リスナー」をサブスクライブして、オブザーバブルをサブスクライブするたびにプルされます。新しいサブスクライバーは、サーバーに再度アクセスしなくても値がキャッシュされます。
したがって、私の「消費者」(Angular Directive)内で、次のようなことをしたいと思います。
// ... countryInput directive code:
COUNTRIES_LOADED.subscribe(function (response) {
// Fill in countries into scope or ctrl
scope.countries = response.countries;
});
COUNTRIES_LOADEDオブザーバーの将来のサブスクライバーは、$ httpリクエストをトリガーしてはなりません(MUSTNOT)。同様に、ディレクティブがページに含まれない場合、$ httpが呼び出されることはありません。
上記の解決策は機能しますが、このアプローチの潜在的な欠点とメモリへの影響を認識していません。これは有効な解決策ですか? RxJを使用してこれを達成するためのより良い/より適切な方法はありますか?
どうもありがとう!
私はここで答えを見つけました(少し違う名前が付けられています) rxjsはサブスクライブ時にpromiseを1回だけ使用します
したがって、私の例では、答えは次のように単純です。
var loadCountries = function () { return $http.get('/countries'); };
var observable = Rx.Observable.defer(loadCountries).shareReplay();
Rx.Observable.fromPromise(promise)
を使用する
fromPromise:
Promises/A +仕様に準拠したPromiseおよび/またはES2015に準拠したPromise、またはそのPromiseを監視可能なシーケンスに戻すファクトリ関数を変換します。
例:
var source = Rx.Observable.fromPromise(promise);
var subscription = source.subscribe(
function (x) {
console.log('Next: %s', x);
},
function (err) {
console.log('Error: %s', err);
},
function () {
console.log('Completed');
});
更新
rxjs6メソッドは from
これがObservablesの使用方法です。getuser(username)
というメソッドがあるとします。
//Returns an observable
getUser(username){
return $http.get(url)
.map(res => res.json());
}
そして、あなたはそれを以下のように使うことができます
getUser.subscribe(res => console.log(response));
しかし、promiseを使用したい場合
//Returns an Promise
//Donot forget to import toPromise operator
getUser(username){
return $http.get(url)
.map(res => res.json())
.toPromise();
}
そして、あなたはそれを以下のように使うことができます
getUser.then(res => console.log(response));