Reputation: 12972
I was wondering whether it's possible to wait for a callback before continuing a process.
I'm using a library that handles a future internally and then if it was successful, does a callback, otherwise handles the error internally with no callback.
Now I'm trying to use this library to create an instance, then fill it with random test data and then update that entity.
Map generateRandomizedInstance() {
lib.createEntity((result1){
result1["a"] = generateRandomA();
result1["b"] = generateRandomB();
result1["c"] = generateRandomC();
...
lib.updateEntity(result1, (result2){
// want to return this result2
return result2;
})
});
}
This would be fine if I'm only creating one entity and updating it once, but I want to create lots of random data:
ButtonElement b = querySelector("button.create")..onClick.listen((e){
for (int i = 0; i < 500; i++) {
generateRandomizedInstance();
}
});
It doesn't take long for this code to crash spectacularly as the callbacks aren't coming back fast enough.
I've tried changing the method signature to
generateRandomizedInstance() async {
and then doing:
for (int i = 0; i < 500; i++) {
print(await generateRandomizedInstance());
}
but that await syntax seems to be invalid and I'm not completely sure how to wrap that callback code in some kind of future that I can wait for the callback to come back before continuing to the next iteration of the loop.
I've tried a while loop at the end of generateRandomizedInstance
that waits for a result variable to not be null, but that kills the browser and seeing as I'm not always getting a callback, in some cases it could cause an infinite loop.
Any ideas / suggestion on how to pause that for loop while waiting for the callback?
Upvotes: 4
Views: 2773
Reputation: 657376
This should do what you want:
Future<Map> generateRandomizedInstance() {
Completer<Map> c = new Completer<Map>();
lib.createEntity((result1){
result1["a"] = generateRandomA();
result1["b"] = generateRandomB();
result1["c"] = generateRandomC();
...
lib.updateEntity(result1, (result2){
// want to return this result2
c.complete(result2);
})
});
return c.future;
}
ButtonElement b = querySelector("button.create")..onClick.listen((e) async {
for (int i = 0; i < 500; i++) {
await generateRandomizedInstance();
}
});
Upvotes: 8