У меня есть асинхронная функция, которая выполняет сетевой запрос, и я хочу убедиться, что вызовы функции ожидают завершения всех предыдущих вызовов, прежде чем делать сетевой запрос. Я также хочу убедиться, что вызовы функции приводят к сетевым запросам в том же порядке.
Я придумал базовое решение, используя List<Completer>
. Ниже приведен упрощенный пример, который можно запустить на DartPad. Обратите внимание, что пример очень упрощен и содержит несколько вызовов, чтобы проиллюстрировать идею - в реальном мире вызовы функции могут поступать из разных мест - таймеры, взаимодействие с пользователем и т. Д.
import 'dart:async';
int i = 0;
List<Completer> funcCompleters = [];
Future<void> func() async{
// Make sure that subsequent calls wait for us
Completer c = Completer();
funcCompleters.add(c);
// Wait for any previous calls
if( funcCompleters.length > 1 ) await funcCompleters[funcCompleters.length-2].future;
// Simulate a lengthy operation, such as a network request
await Future.delayed(Duration(milliseconds: 500));
// Generate some output so we can see what happens
i += 1;
print('i: $i funcCompleters.length: ${funcCompleters.length}');
// Let any queued calls execute
c.complete();
funcCompleters.remove(c);
}
void main() async {
await func();
func();
func();
Timer(Duration(milliseconds: 800), () => func());
await func();
func();
await func();
await func();
func();
func();
Timer(Duration(milliseconds: 1), () => func());
func();
}
Работает, но коряво.
По сути, идея состоит в том, чтобы поставить функцию в очередь при любом ее вызове и выполнять вызовы один за другим.
Есть лучший способ сделать это?
Future.forEach
- person pskink   schedule 20.03.2021StreamController
иStream.asyncMap
- в документации говорится: Создает новый поток с каждым событием данных этого потока, асинхронно отображаемым на новое событие. Это действует как map, за исключением того, что convert может вернуть Future, и в этом случае этот поток ожидает завершения этого future-объекта, прежде чем продолжить работу со своим результатом. - person pskink   schedule 20.03.2021