2016-10-08 9 views
3

나는 Rx를 처음 사용하고 HTTP로 일부 토큰 관리 작업을하고있다. 토큰을 추적하고이 토큰이 모든 아웃 바운드 http 요청의 헤더에 추가된다는 아이디어가 있습니다.RxJs - 다음에서 호출 대상에서 Observable 구독

const request = (name, token, time) => { 
    console.log('attempt ' + name + ' with token ' + token); 
    return Rx.Observable.timer(time) 
     .do(() => { 
     console.log('sent ' + name + ' with token ' + token); 
     }) 
     .mapTo({ newToken: 'baz' }) // token baz arrives 
     .do(r => { 
     console.log('response for ' + name + ' received'); 
     }); 
}; 

const token$ = new Rx.ReplaySubject(1); 

token$.switchMap(token => request('request1', token, 0)) 
    //.do(rs => { token$.next(rs.newToken); }) // fails, causes a loop 
    .subscribe(
     // (rs) => { token$.next(rs.newToken); } // also fails with loop 
    ); 

token$.switchMap(token => request('request2', token, 1000)) 
    .subscribe(); 

// emit a token 

token$.next('bar'); 

// but how do I ensure 'request2' is sent with token 'baz' ? 

내 질문이 관찰 요청에서 반환 어떻게 bazReplaySubject를 업데이트 할 수 있습니다 :

코드는 지금처럼 보인다?

token.switchMap(token => request('request1', token, 0)) 
    .do(rs => { token.next(rs.newToken); }) 
    .subscribe(); 

을하지만이 루프로를 전송하고 request1 토큰 baz을 반복한다 :

나는과 같이 request1do에서 next를 호출했습니다. 피사체에 nextdo과 같이 구독해도됩니다. Observable? 나는 그것이 어떤 Rx 계약이나 뭔가를 위반하는지 궁금 하네.

나는이 같은 request1 시도 :

token.switchMap(token => request('request1', token, 0)) 
    .subscribe(rs => { token.next(rs.newToken); }); 

을 그러나 같은 루프가 발생합니다. 아마 내가 next에 전화하고 있기 때문에 나는 switchMap-over!

어떻게 해결할 수 있습니까? 감사! 다음 재사용해야하는, 내가 바로이 map 기능이 실제로 일부 외부 전화를하고 토큰을 반환하도록되어 이해한다면

jsbin here

+0

당신이 명확히 주시겠습니까 (또한 우리가 switch의 유용한 동작을 잃을 것이다. RxJs에는 switchScan 없음). 토큰이 서버에 의해 할당 되었습니까? 그렇다면 'foo'로 변경 한 다음 'bar'로 변경하는 이유는 무엇입니까? 새로운 토큰을 받으면 즉시 행동합니까? – Meir

+0

토큰이 서버에 의해 다시 전송됩니다. 방금 위의'foo'와'bar' 토큰을 테스트에 추가했습니다. request1은 토큰'bar'를 가지고 있어야하고 request2는 서버가 리턴 한 토큰'baz'를 가져야합니다 (현재는 그렇지 않습니다). 나는'do' 함수에서'next (rs.newToken) '을 호출하고'subscribe' 콜백에서도 이것을 시도했다. jsbin을 보면 어떻게 실패하는지 알 수 있습니다. – ghostypants

+0

코드를 약간 정리하고'foo' 난센스를 삭제했습니다. 답장을 보내 주셔서 감사합니다! – ghostypants

답변

0

좋아? 그리고 return { newToken: 'baz' };은 조롱을당한 결과 일뿐입니다.

token.next('bar')replaySubject에 새 토큰을 추가 할뿐만 아니라 새 요청을 발생시킵니다.

newRequestSubjecttokenSubject에서 분할해야합니다. 그렇게하면 새 요청을 실행하지 않고도 새 토큰을 밀어 넣을 수 있습니다. 이미 요청한 것처럼 끝없는 반복으로 끝날 수 있습니다.

그런 다음 requestSubject을 준비하는 newRequestSubject.withLatestFrom(tokenSubject).switchMap(request).subscribe()를 사용하여 요청을 밀어 newRequestSubject.next(200, 'request1')를 호출 할 수 있습니다.

tokenSubjectreplaySubjectbehaviorSubject으로 바꿀 수 있으므로 생성시 초기 토큰을 전달할 수 있습니다.

request 안에는 tokenSubject.next()으로 전화하여 토큰을 업데이트 할 수 있습니다.

부작용으로, 예를 들어 mergeScan과 같이 주제를 모두 제거하면 이전 요청에서 결과를 가져 와서 다음 결과로 가져올 수 있지만 더 좋을 수도 있습니다. 조금 더 이해하기 어렵다.

newRequestSubject.mergeScan(request, initialToken); 

+0

답변 해 주셔서 감사합니다. 나는 mergeScan을 확실히 조사 할 것이다. 핵심 문제로 혼란 스럽다고 느끼면서 간격 자료를 삭제하는 질문을 업데이트했습니다. 이제는 임의의 간격을 사용하고 있습니다. – ghostypants

+0

OK 제가 제안한 것과 비슷한 것을 시도하고이 [jsbin] (http://jsbin.com/huwita/44/edit?js, console)으로 감았습니다. 내가 두 과목을 사용하고 있지만, 일하는 것처럼 보입니다. 감사! – ghostypants

관련 문제