2016-12-23 53 views
5

Tüketici tarafından iptal edilmesi, takeUntil kullanılarak çağrılabilir, ancak bu mutlaka çok dinamik değildir. Bu durumda, denklemin üretici tarafındaki bir Gözlemlenebilir'i iptal etmeye çalışıyorum, aynı şekilde bir söz zincirinde bir Söz Sözü'nü iptal etmek isteyebilirsiniz (ki bu da doğal hizmet ile mümkün değildir).Üretici tarafından Gözlemlenebilir taraftan değil, tüketici tarafında değil

Bu Gözlemlenebilir bir yöntemden döndüğümü varsayalım. (Bu Kuyruk kütüphanesi, bir metin dosyasına okuyan/yazan basit bir kalıcı kuyruktur, okuma/yazma işlemlerini kilitlememiz gerekir, böylece hiçbir şey bozulmaz). , Gözlemlenebilir sadece hayır sonucu (ler) ile boş bir gözlemlenebilir geri göndermek Ben kilidi elde edemiyorsanız

  1. , nasıl "iptal" olabilir -

    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(); 
          } 
         }); 
    
    }; 
    

    Ben 2 farklı sorular? Geçerli dönüşün iptal edilip edilmediğine karar vermek için her dönüş çağrısında/else mantığı varsa gerçekten yapmak zorunda mıyım ve eğer öyle ise boş bir Gözlemlenebilir mi? Boş olarak, herhangi bir olasılık olmadan ve onNext için herhangi bir değer içermeyen, ondan beri/onComplete üzerindeki basit yangınların Gözlemlenebilir olduğunu kastediyorum. Teknik olarak, bu boş bir Gözlemlenebilir sanmıyorum, bu yüzden var ise, gerçekten denen şeyin ne olduğunu arıyorum.

  2. kod bu özel dizisi bakarsak: ne yapıyorum yöntemin üstündeki ret bir başvuru depolamak ve daha sonra bir adım daha sonra yeniden başvuran

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

. Aradığım şey, zincirin dışındaki bazı durumları ayarlamak zorunda kalmadan removeOneLine() 'tan JSON.parse()' a atılan değeri iletmenin bir yoludur (ki bu basitçe ineleganttır).

cevap

3

1) Bu sizin yöntem çalışır acquireLock bağlıdır - ama, kilidi elde edemez durumda bir catch ile Akışınızı oluşturabilir ve geri dönüş akışı ayarlamak eğer bir hata atar olduğunu varsayıyorum boş bir: tanımına göre

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

teşekkürler @olsn, Bölüm 2'yi takip ediyorum (harita ve mapTo arasındaki farkı bilmeme rağmen), fakat bölüm 1 ile ilgili olarak, takip etmiyorum, başka bir deyişle açıklamayı aklınızdan çıkarır mısınız? –

+0

part1, mapTo' 'mapTo' to_ _map doğrudan bir argüman alır sadece budur' (üzgün, cevap kötü structued biraz olabilir) temelde map' 'arasındaki fark kod bloğunun son 4 satır ve 'map' bir fonksiyon alırken,' .mapTo (val) 'de' .map (() => val) ' – olsn

+0

olarak yazılabilir. Tamam, anladığım şekilde düzenleyeceğim, lütfen çekinmeyin düzenlemelerimi düzenle :) –

2

:

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

2) durum bilgisi harici değişken yedek için sadece bir mapTo zincirlemek olabilir İptal, bu, aşağı akışta bir değer göndermenin gözlemlenebilir olmasını önlemektir.

observable.filter(_ => lockAcquired) 

Bu yalnızca lockAcquired doğrudur aşağı eğer bir bildirim gönderecektir:

kadar basit olabilir: Bir değer iterek bir gözlemlenebilir önlemek için, filtreyi kullanabilirsiniz.