Aus öffentlichen Paketdaten erstellte Orientierung.
Das Queue-Paket ermöglicht Entwicklern die flexible und zentrale Verwaltung und das Warten auf mehrere asynchrone Operationen (Futures) aus verschiedenen Quellen. Es erlaubt das Anordnen von Futures an einer Stelle im Code und das Warten auf deren Ergebnisse an einer anderen Stelle, wodurch die Kontrolle über den Ablauf asynchroner Ausführung verbessert wird. Ideal für Szenarien, die koordinierte asynchrone Aufgaben erfordern, wie beispielsweise Batch-Verarbeitung oder sequenzielles Datenabrufen. Das Paket ist leichtgewichtig und kompatibel mit allen wichtigen Plattformen, was es für plattformübergreifende Anwendungen geeignet macht. Es verbessert die Lesbarkeit des Codes, indem die Aufgabenerstellung von der Ergebnisverarbeitung getrennt wird.
Anwendungsfälle
Batchverarbeitung von asynchronen Operationen
Koordinierung mehrerer API-Aufrufe
Verzögerte Ausführung asynchroner Aufgaben
Asynchrone Workflows in UI-Komponenten verwalten
Datensynchronisierung beim Laden über Module hinweg
Hauptmerkmale
zentrale Zukunftswarteschlange
Warten Sie zukünftige Ereignisse von überall aus
Unterstützt mehrere asynchrone Quellen
Plattformübergreifende Kompatibilität
Minimales Boilerplate
Thread-sichere Operation
Geeignet für
Entwickler, die komplexe asynchrone Abläufe verwalten
Apps, die geordnete asynchrone Ausführung erfordern
Teams, die reaktive oder Zustandsverwaltungs-Muster verwenden
Projekte für mehrere Plattformen
Codebases mit hoher asynchroner Komplexität
Hinweise
Nicht für Echtzeit-Streaming ausgelegt
Erfordert sorgfältige Verwaltung des Warteschlangen-Lebenszyklus
Kann den Speicherverbrauch bei großen Warteschlangen erhöhen
Am besten geeignet für endliche, vorhersehbare asynchrone Sequenzen
Behandelt interne Wiederholungslogik oder Fehlerbehebung nicht
Original-README
Originaler README-Schnappschuss aus dem verknüpften Quell-Repository. Aktuelle Inhalte finden Sie im Repository.
queue
Easily queue futures and await their values.
This library allows you to send a future to central queue. The queue will execute the futures in the order they are queued and once the future is complete it will return its result.
My use case was to rate limit calls to bluetooth devices. There were multiple bluetooth devices connected that may have different commands being sent from lots of areas in the app. The devices were tripping over themselves and not responding. A stream wasn't the appropriate tool as I needed to get the result back. Hence a library was born.
Alternative use cases could be spidering a website, downloading a number of files, or rate limiting calls to an API.
Usage
The most simple example:
import'package:queue/queue.dart';
main() async {
final queue = Queue();
//Queue up a future and await its resultfinal result = await queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
//Thats it!
}
A proof of concept:
import'package:queue/queue.dart';
main() async {
//Create the queue containerfinalQueue queue = Queue(delay: Duration(milliseconds: 10));
//Add items to the queue asyncroniously
queue.add(()=>Future.delayed(Duration(milliseconds: 100)));
queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
//Get a result from the future in line with awaitfinal result = await queue.add(() async {
awaitFuture.delayed(Duration(milliseconds: 1));
return"Future Complete";
});
//100, 10, 1 will reslove in that order.
result == "Future Complete"; //true
}
Parallel processing
This doesn't work in batches and will fire the next item as soon as as there is space in the queue
Use [Queue(delayed: ...)] to specify a delay before firing the next item
import'package:queue/queue.dart';
main() async {
final queue = Queue(parallel: 2);
//Queue up a future and await its resultfinal result1 = await queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
final result2 = await queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
//Thats it!
}
On complete
import'package:queue/queue.dart';
main() async {
final queue = Queue(parallel: 2);
//Queue up a couple of futures
queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
// Will only resolve when all the queue items have resolved.await queue.onComplete;
}
Rate limiting
You can specify a delay before the next item is fired as per the following example:
import'package:queue/queue.dart';
main() async {
final queue = Queue(delay: Duration(milliseconds: 500)); // Set the delay here//Queue up a future and await its resultfinal result1 = await queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
final result2 = await queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
//Thats it!
}
LIFO (Last In First Out)
You can configure the queue to process items in LIFO order (last in, first out) by setting the lifo parameter:
import'package:queue/queue.dart';
main() async {
// Create a LIFO queuefinal queue = Queue(lifo: true);
// Add items to the queue
queue.add(() => Future.delayed(Duration(milliseconds: 100))); // Will be processed last
queue.add(() => Future.delayed(Duration(milliseconds: 50))); // Will be processed second
queue.add(() => Future.delayed(Duration(milliseconds: 10))); // Will be processed first
}
Adding items to the front of the queue
You can add items to the front of the queue to process them sooner using the addToFront parameter:
import'package:queue/queue.dart';
main() async {
final queue = Queue();
// Add a regular item to the queue
queue.add(() => Future.delayed(Duration(milliseconds: 100)));
// Add an urgent item that should be processed next
queue.add(
() => Future.delayed(Duration(milliseconds: 50)),
addToFront: true
);
}
Cancel
If you need to stop a queue from processing call Queue.cancel();
This will cancel the remaining items in the queue by throwing a QueueCancelledException.
A cancelled queue is "dead" and should be recreated. If you try adding items to the queue after you
call cancel, it will throw a QueueCancelledException.
If you have no reason to listen to the results of the items, simply call dispose.
If you want to wait until all the items which are inflight complete, call Queue.onComplete first.
Disposing
If you need to dispose of the queue object (best practice in flutter any any time the queue object will close)
simply call queue.dispose();
This is necessary to close the Queue.remainingItems controller.
Reporting
If you want to query how many items are outstanding in the queue once, you can use the getter remainingItemCount.
import'package:queue/queue.dart';
final queue = Queue();
final count = queue.remainingItemCount;
If you want to get notified when the remainingItemCount changes, listen to the Queue.remainingItems stream.
import'package:queue/queue.dart';
final queue = Queue();
final remainingItemsStream = queue.remainingItems.listen((numberOfItems)=>print(numberOfItems));
//Queue up a couple of futures
queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
queue.add(()=>Future.delayed(Duration(milliseconds: 10)));
// Will only resolve when all the queue items have resolved.await queue.onComplete;
remainingItemsStream.close();
queue.dispose(); // Will clean up any resources in the queue if you are done with it.
Contributing
Pull requests are welcome. There is a shell script ci_checks.sh that will run the checks to get
past CI and also format the code before committing. If that all passes your PR will likely be accepted.