Ho due compiti asincroni che devono essere completati - diciamo che sono "fare una torta" ( make
) e "cuocere una torta" ( bake
). Ho anche bisogno di ripulire dopo aver fatto tutto - "pulire la cucina" ( cleanup
). bake
dipende da make
, e voglio cleanup
quando le cose sono fatte. Tuttavia, ci sono alcune complicazioni:
- Se qualche bella persona ha già
made
della torta, tutto ciò che devo fare èbake
. - Se si verifica un problema durante
make
- forse mi stanco di tutto questo business pie - ho bisogno dicleanup
. - Se si verifica un problema durante
bake
- il forno esplode - Devo anchecleanup
.
Il mio primo passaggio sembra qualcosa del genere:
func pieTime()
if !pie.isMade()
make()
else if !pie.isBaked()
bake()
else
cleanup(null)
func make()
makeThePie(completion: {
if pie.hasError()
cleanup(error)
else
bake()
})
func bake()
bakeThePie(completion: {
if pie.hasError()
cleanup(error)
else
cleanup(null)
})
func cleanup(error)
if error != null
shout("what the ***: %s", error.string())
destroy(pie)
Questo non è male, ma il mio problema principale con questo approccio è che non esiste un singolo punto di uscita dal flusso. cleanup
viene chiamato da un sacco di posti. Man mano che la gestione degli errori diventa più complicata e si aggiungono più chiamate asincrone alla catena, ci sono sempre più punti di uscita dal flusso per tenere traccia di. Se non riesco a chiamare cleanup
in nessuna di esse, il risultato è una cucina inutilizzabile.
Fondamentalmente, sto cercando qualcosa come un do / catch / finally per le chiamate asincrone. L'unica cosa che potrei inventare è una coda: metti in coda solo le attività di cui hai bisogno e fai una coda di pulizia alla fine, ma sembra un po 'troppo pesante per due soli compiti, come questa istanza. C'è un modello ben definito per questo problema?