Следующий код может быть плохой практикой при использовании в большой очереди задач, но если вы уверены, что массив задач не будет превышать адекватный размер - это может работать просто отлично:
Future<List<T>> runOneByOne<T>(List<T Function()> list) {
if (list.isEmpty) {
return Future.value(null);
}
Future task = Future<T>.microtask(list.first);
final List<T> results = [];
for (var i = 1; i < list.length; i++) {
final func = list[i];
task = task.then((res) { results.add(res); return Future<T>.microtask(func); });
}
return task.then((res) { results.add(res); return results; });
}
Он выполняет функции одну за другой в исходном порядке, заключая одну Future
в другую. results
Массив используется для хранения возвращаемых значений, возвращая все значения в конце.
Выполнение останавливается и выбрасывается, если возникла ошибка. В этом случае массив результатов теряется. Вы можете добавить try {...}
closure к каждой microtask
оболочке, чтобы игнорировать ошибки и возвращать null
в этой конкретной задаче, сохраняя другие значения в массиве results
.
Пример использования:
runOneByOne<int>([
() { print("First"); return 1; },
() { print("Second"); return 2; },
() { print("Third"); return 3; },
]).then((results) {
print(results); // List<int> [ 1, 2, 3 ]
});