/// Runs asynchronous operations one at a time without allowing a failed /// operation to poison the queue tail. class SerialFutureQueue { Future _tail = Future.value(); Future run(Future Function() operation) { final result = _tail.then((_) => operation()); _tail = _settle(result); return result; } Future get settled => _tail; void reset() { _tail = Future.value(); } static Future _settle(Future operation) async { try { await operation; } catch (_) { // The returned operation future carries the error to its caller. The // internal tail only represents when the queue may start its next item. } } }