So kombinieren Sie zwei asynchrone Netzwerkanrufe mit ReactiveCocoa

8

Ich habe zwei Netzwerksignale, die ich zusammenführen möchte, aber mit einigen Einschränkungen.

Rufen wir die Netzwerksignale A und B auf. A verwendet AFNetworking, um eine Ressource im Cache nachzuschlagen und jede Antwort für diese Anfrage sofort zurückzugeben. B berücksichtigt auch den Cache, kann jedoch zur Revalidierung der Antwort auf den Remote-Server wechseln.

Ok, also was ich machen möchte:

Anfrage A:

  • sollte so schnell wie möglich senden.
  • Wenn B bereits einen sendNext gesendet hat, ignorieren wir einfach A.
  • Wenn etwas schief geht und A einen Fehler erzeugt, sollten wir ihn einfach ignorieren.

Anfrage B:

  • sollte so bald wie möglich sendNext senden, auch wenn A bereits eine sendNext-Nachricht gesendet hat.
  • Wenn etwas schief geht, interessiert mich der Fehler von B, aber es sollte nicht aufhören A.

Meine derzeitige Lösung ist dies:

%Vor%

Ich weiß, dass diese Lösung meine Anforderungen nicht erfüllt, also frage ich mich, ob mir jemand mit einer besseren Lösung helfen könnte.

Meine Lösung (abgeleitet von @ JustinSpahr-Summers Antwort):

%Vor%     
Andi 04.12.2013, 12:47
quelle

1 Antwort

12

Diese Frage ist schwer zu beantworten, da Ihre gewünschte Fehlerbehandlung grundsätzlich nicht mit dem RACSignal API-Vertrag kompatibel ist, der besagt, dass Fehler haben eine Ausnahmesemantik .

Die einzige Möglichkeit, zu ignorieren, aber dennoch Fehler zu vermeiden, besteht darin, sie an anderer Stelle umzuleiten. In diesem Beispiel verwende ich ein Thema:

%Vor%

... Sie können aber auch eine Eigenschaft oder einen anderen Benachrichtigungsmechanismus verwenden.

Ich werde weiterhin die oben angegebenen remoteSignal und cacheSignal verwenden, mit einigen Änderungen. Hier ist das Verhalten, das wir von ihnen wollen:

  1. remoteSignal sollte seine Fehler an remoteErrors senden
  2. cacheSignal sollte abgebrochen werden, sobald remoteSignal einen Wert
  3. sendet
  4. Fehler von beiden Signalen sollten die anderen nicht beenden
  5. Wir wollen die Werte von cacheSignal und remoteSignal zusammenführen, damit wir den fernen Wert immer noch erhalten, nachdem der Cache gelesen wurde

Betrachten wir in diesem Zusammenhang remoteSignal :

%Vor%

Die -doError: und -finally: kontrollieren das remoteErrors Subjekt und erfüllen unsere erste Anforderung oben. Da wir remoteSignal an mehreren Stellen verwenden müssen (wie Sie in der obigen Liste sehen können), verwenden wir -replayLazily , um sicherzustellen, dass die Nebenwirkungen nur einmal auftreten.

cacheSignal ist nahezu unverändert. Wir müssen nur -takeUntil: verwenden, um sicherzustellen, dass es beendet wird, wenn remoteSignal einen Wert sendet (aber nicht, wenn es einen Fehler sendet):

%Vor%

Schließlich wollen wir ihre Werte zusammenführen, so dass beide Signale gleichzeitig gestartet werden und ihre Werte in beliebiger Reihenfolge eintreffen können:

%Vor%

Wir ignorieren hier Fehler, weil ein Fehler von beiden beide beenden würde (da sie jetzt kombiniert wurden). Unser Fehlerbehandlungsverhalten ist bereits oben behandelt.

Und trotz der Zusammenführung stellt die Verwendung von -takeUntil: auf cacheSignal sicher, dass es unmöglich ist, einen Wert nach remoteSignal zu senden.

Wenn Sie einen anderen Blick auf die Liste der Anforderungen werfen, können Sie sehen, welche Operatoren verwendet wurden, um diese zu erfüllen:

  1. [-doError:] remoteSignal sollte seine Fehler an remoteErrors senden
  2. [-takeUntil:] cacheSignal sollte abgebrochen werden, sobald remoteSignal einen Wert
  3. sendet
  4. [-catchTo:] Fehler von beiden Signalen sollten die anderen nicht beenden
  5. [+merge:] Wir möchten die Werte von cacheSignal und remoteSignal zusammenführen, damit wir den fernen Wert immer noch erhalten, nachdem der Cache gelesen wurde
Justin Spahr-Summers 06.12.2013, 18:53
quelle

Tags und Links