Reputation: 388
Okay, so I have a List of Files and I need to run a function on each member of the list. I essentially want to do something like this:
for(File file in files) {
functionThatReturnsAFuture(file);
}
But obviously this won't work, since the function that returns a Future fires of asynchronously. Is my only option something like this?
List<File> files = new List<File>();
// Add files somewhere
Future processFile(int i) {
return new Future.sync(() {
//Do stuff to the file
if(files.length>i+1) {
return processFile(i+1);
}
});
}
processFile(0);
EDIT: I suppose more context is important. The end goal is to combine several files into a single JSON object for submitting to a server. The FileReader object uses events to perform a read, so I used a Completer to create a wrapper function that provides a Future. I could let all of these run asynchronously, and then fire off an event that submits it when they are all done, but that's comparatively a lot of setup vs. a for-each-loop that makes it all work (if one exists, anyway). The core issue is needing to run a Future-returning function on a List of files and then perform an action that depends on them all having completed.
Upvotes: 12
Views: 24137
Reputation: 19
This library can help https://pub.dartlang.org/packages/heavylist
HeavyList<File> abc = new HeavyList<File>([new File(), new File(), ]);
abc.loop(new Duration(seconds: 1), (List<File> origin) {
print(origin);
}, (File item, Function resume) {
//simulating an asynchronous call
print(item);
//move to next item
resume();
});
Upvotes: -1
Reputation: 657406
Dart supports async
/await
since quite some time which allows it to write as
someFunc() async {
for(File file in files) {
await functionThatReturnsAFuture(file);
}
}
Upvotes: 15
Reputation: 21383
When you need to wait for multiple Futures to complete and you don't care about the order, you can use Future.wait():
Future.wait(files.map(functionThatReturnsAFuture))
.then((List response) => print('All files processed'));
If order is important you can use Future.forEach() instead which waits for each Future to be completed before moving to the next element:
Future.forEach(files, functionThatReturnsAFuture)
.then((response) => print('All files processed'));
Upvotes: 40