2017-11-14 1 views
0

TLDR:Observed配列に完了を指示する方法を教えてください。例えば、this jsBinを参照してください。Observableに配列が完全であることを伝えるにはどうすればいいですか

私はObservablesには新しいので、間違った角度から来ている可能性があります。下記のコードor this jsBinを入力すると、ユーザーのサイト配列を「完了」するために、何をどうやってやるべきですか。それが見つからない場合(最初の)[http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-first]はしかし、エラーをスローする必要があること

let firstUser = { 
    name: 'Susan', 
    sites: [ 
    {company: 'ABC Co', role: 'admin'}, 
    {company: 'XYZ Co', role: 'reader'} 
    ] 
}; 

user = new Rx.BehaviorSubject(firstUser); 

function authorized(authRoles) { 
    // check if the current user has one of the authorizedRoles roles 
    return this.user 
     .do(user => console.log("Checking user: ",JSON.stringify(user))) 
     .flatMap(user => user.sites) 
     .do(res => console.log("Mapped user roles: ",res)) 
     .first(site => authRoles.indexOf(site.role) !== -1) // only return when a role matches 
     .do(res => console.log('First: ',res)) 
     .map(res => true) 
} 

// This one finds a match and completes 
authorized(['writer','admin','reader']).subscribe(res =>{ 
    console.log("1: isAuthorized?: ",res); 
}, err => { 
    console.log("1: ERROR: User is not authorized!"); 
},() => { 
    console.log("1: Authorized check completed!"); 
}); 

// This one never completes 
authorized(['writer','foo']).subscribe(res =>{ 
    console.log("2: isAuthorized?: ",res); 
}, err => { 
    console.log("2: ERROR: User is not authorized!"); 
},() => { 
    console.log("2: Authorized check completed!"); 
}); 

注のみ観察可能に完了した場合。

一致が見つかった場合、上記は正常に戻り、完了しますが、user.sitesの配列が決して完了しないため、一致しないとエラーは発生しません。

アレイを完成させる方法はありますか?

// 
// Pretend that fetchedUser is fetched in a safer/more sane way 

// fetch the user and set it 
let fetchedUser; 
user.subscribe(user => fetchedUser = user); 

function authorized2(authRoles) { 
    // check if the current user has one of the authorizedRoles roles 
    return Rx.Observable.of(this.fetchedUser.sites) 
     .do(sites => console.log("auth2: Checking users sites: ",sites)) 
     .flatMap(sites => sites) 
     .do(res => console.log("Mapped user roles: ",res)) 
     .first(site => authRoles.indexOf(site.role) !== -1) // only return when a role matches 
     .do(res => console.log('First: ',res)) 
     .map(res => true) 
} 

私は、これは純粋な観測を使用して動作させるために重要な、まだ簡単なステップをしないのですように私は感じる:私は、私は/最初のユーザーに加入フェッチあれば、それは仕事を得ることができます。あなたの助けを前もってありがとう!

+0

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md#usage – Dom

+0

@Dom私が何かわかりませんになっている。 2番目の例では、そのようなものを使用していますが、正しい方法であるとは思わないか、そうでないと言う記事などを見つけることはできません。 – jrose

答えて

1

Rx.Observable.of(this.fetchedUser.sites)は、その引数を観測可能なシーケンスに変換して完了します。これにより、.first演算子は例外をスローします。件名はthis.userで終わることはありません。 this.user.take(1)またはRx.Observable.of(fetchedUser)に変更し、完了したい場合は動作の対象にすることができます。または.first.mapに変更して、ユーザーが権限がない場合はfalseを返すようにすることもできます。以下は、take演算子の使用例です。

const user = Rx.Observable.create((o) => { 
 
    window.setTimeout(() => { 
 
    o.next({ 
 
     name: 'Susan', 
 
     sites: [ 
 
     {company: 'ABC Co', role: 'admin'}, 
 
     {company: 'XYZ Co', role: 'reader'} 
 
     ] 
 
    }); 
 
    }, 1000); 
 
}); 
 

 
function authorized(authRoles) { 
 
    return user 
 
     .take(1) 
 
     .flatMap(user => user.sites) 
 
     .first(site => authRoles.indexOf(site.role) !== -1) 
 
     .map(res => true); 
 
} 
 

 
authorized(['writer','admin','reader']).subscribe(res =>{ 
 
    console.log("1: isAuthorized?: ",res); 
 
}, err => { 
 
    console.log("1: ERROR: User is not authorized!"); 
 
},() => { 
 
    console.log("1: Authorized check completed!"); 
 
}); 
 

 
authorized(['writer','foo']).subscribe(res =>{ 
 
    console.log("2: isAuthorized?: ",res); 
 
}, err => { 
 
    console.log("2: ERROR: User is not authorized!"); 
 
},() => { 
 
    console.log("2: Authorized check completed!"); 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.min.js"></script>

あなたの例を見た後、私はあなたがRxJsで、この問題を解決しようとしている理由を疑問に残っています。 RxJsはデータのストリームで動作するように調整されていますが、静的な値で動作しています。たぶんあなたのアプリは実際にあなたのアプリで実際に起こっていることを単純化しているだけかもしれませんが、あなたはRxJを同期させずにやっていることを達成でき、はるかに簡単です。次に例を示します。

function authorized(authRoles) { 
    return firstUser.sites.some(x => authRoles.includes(x)); 
} 
+0

私はJSBinでRx.Observable.ofを使って説明しましたが、実際に知りたいことは、Observable配列を "完了"するために何か知っているのか、それともどういうことですか?私が与えた例は実際にどのように使用すべきかということではないが、実際のユースケースに必要なものと同様の論理を示していることは分かっている。書かれているように、あなたの答えの最後の部分にスポットがあります。 – jrose

+0

@jose '.take(1)'は、1つの項目が流れた後にストリームを完成させます。どのような状態で完了したいですか? – bygrace

+0

私はすべての "サイト"が流れてしまった後にそれを完了したい。 – jrose

関連する問題