2016-12-23 2 views
5

소비자 측에서 취소하는 경우 takeUntil을 사용하여 호출 할 수 있지만 반드시 동적 일 필요는 없습니다. 이 경우 프로 스펙 체인 내에서 Promise를 취소하려는 것과 동일한 방법으로 Observable을 방정식의 생산자 측에서 취소하려고합니다 (이는 네이티브 유틸리티로는 불가능합니다).소비자 측이 아닌 생산자 측에서 Observable 취소

내가이 Observable을 메소드에서 반환했다고 가정 해 봅시다. (이 큐 라이브러리는 텍스트 파일을 읽고 쓰는 단순한 영구 큐이므로 아무것도 읽지 않도록 쓰기/읽기를 잠글 필요가 있습니다.) , 관찰 그냥 아무 결과 (들)과 함께 빈 관찰 가능한을 다시 보내 내가 잠금을 획득 할 수없는 경우

  1. , 어떻게 내가 "취소"할 수 -

    Queue.prototype.readUnique = function() { 
    
        var ret = null; 
        var lockAcquired = false; 
    
        return this.obsEnqueue 
         .flatMap(() => acquireLock(this)) 
         .flatMap(() => { 
          lockAcquired = true; 
          return removeOneLine(this) 
         }) 
         .flatMap(val => { 
          ret = val; // this is not very good 
          return releaseLock(this); 
         }) 
         .map(() => { 
          return JSON.parse(ret); 
         }) 
         .catch(e => { 
          if (lockAcquired) { 
           return releaseLock(this); 
          } 
          else { 
           return genericObservable(); 
          } 
         }); 
    
    }; 
    

    나는 두 가지 질문이? 각 체인이 현재 체인이 취소되었는지 여부를 결정하기 위해 if/else 로직을 수행해야합니까? 그렇다면 빈 Observable을 반환 하시겠습니까? 비어 있음으로써, Observable은 onNext/onComplete 에러가 발생할 가능성이없고 onNext에 대한 어떠한 값도없이 간단하게 발생한다는 것을 의미합니다. 기술적으로, 나는 이것이 빈 Observable이라고 생각하지 않는다. 그래서 그것이 실제로 존재한다면 그것이 무엇인지를 찾고있다.

  2. 당신은 코드의 특정 시퀀스를 보면 : 내가 무엇을하고 있는가하는 방법의 상단에 마지막 ret에 대한 참조를 저장하고 다음 단계를 나중에 다시 참조하는

    .flatMap(() => acquireLock(this)) 
    .flatMap(() => { 
        lockAcquired = true; 
        return removeOneLine(this) 
    }) 
    .flatMap(val => { 
        ret = val; 
        return releaseLock(this); 
    }) 
    .map(() => { 
        return JSON.parse(ret); 
    }) 
    

. 내가 찾고있는 것은 체인 외부의 상태를 설정하지 않고도 removeOneLine()에서 JSON.parse()로 해고 된 값을 전달하는 방법입니다 (이는 단순히 비 효과적입니다).

답변

3

1) 그것은 당신의 방법을 작동 acquireLock 방법에 따라 달라집니다 -하지만 난 그게, 잠금을 얻을 수없는 경우에 당신이 catch으로 스트림을 만들 수 있으며,에 대체 스트림을 설정하면이 오류가 발생한다고 가정하고 빈 하나 : 당신의 정의에 따르면

let removeLine$ = acquireLock(this) 
    .flatMap(() => this.obsEnqueue 
     .flatMap(() => removeOneLine(this)) 
     .flatMap(val => releaseLock(this).mapTo(val)) 
     .map(val => JSON.parse(val)) 
     .catch(() => releaseLock(this)) 
    ); 
+0

감사합니다. @olsn, 2 부 (지도와 mapTo의 차이는 모르지만)를 따르지 만 1 부에서는 따르지 않습니다. 다른 말로 설명 하시겠습니까? –

+0

part1은 기본적으로 코드 블록의 마지막 4 줄입니다. (미안 해요, 대답은 약간 심하게 구조화 될 수 있습니다) 'map'과'mapTo'의 차이점은'mapTo'가 _map to_에 직접 인수를 취한다는 것입니다. 'map'은 함수를 취하므로'.mapTo (val)'도'.map (() => val)'이라고 쓰여질 수 있습니다. – olsn

+0

ok 나는 그것을 이해하는대로 편집 할 것입니다. 내 편집 편집 :) –

2

:

return Rx.Observable.catch(
     removeLine$, 
     Rx.Observable.empty() 
    ); 

2)이 상태 외부 변수를 절약하려면 당신은 단순히 mapTo을 체인 수 취소의 경우 관측 대상에서 값을 보내지 못하도록하는 것입니다.

observable.filter(_ => lockAcquired) 

이는 lockAcquired에 해당하는 다운 스트림 경우 통지를 보내드립니다 :

처럼 간단 할 수있다 : 값을 밀어에서 관찰을 방지하기 위해, 당신은 필터를 사용할 수 있습니다.