I've seen a few questions here about doing things in parallel but they don't seem to apply my specific issue (or I don't know enough to know if they apply to my issue).
I have a page that needs to make an API calls and display data for a non-fixed/user-configurable amount of servers. My current method is to trigger a single event when the page is opened to make these API calls and yield the state with the new results added into my Map each time.
However, when I use a for...in loop to go over this list of variable length it's going to wait for the completion of one yield* before it moves on to the next server. If my servers happened to be ordered from fastest to slowest repose it works exactly as I want, but all items after a slow server have to wait for it before they get their chance.
My question is how can I execute my yield* for my streams in parallel without putting them in a for...in loop since that is not async?
Example that highlights what I'm doing:
Map serverData = {};
if (event is Load) {
final serverList = await getServers();
for (Server server in serverList) { <- Executes synchronously rather than asynchronously
yield* loadServer(server, serverData);
}
}
loadServer(Server server, Map serverData) async* {
List newData = await getData(server); <- Takes an unknown amount of time
serverData[server.id] = newData;
yield Success(serverData);
}
The only takeaway I got from looking at other answers was to maybe utilize an event that gets triggers for each server rather than doing it all in one event but honestly, I'm not sure how that would help me.
Thanks for any guidance that can be offered!
Hi @TheMeanCanEHdian 馃憢
Thanks for opening an issue!
I would recommend adding a new event when each server is loaded rather than awaiting the response synchronously.
if (event is Load) {
final serverList = await getServers();
for (Server server in serverList) {
getData(server).then((newData) => add(NewDataReceived(server.id, newData)));
}
} else if (event is NewDataReceived) {
yield Success(Map.of(state.serverData)..addAll({event.serverId: event.data}));
}
Hope that helps 馃憤
I'll give this a try and report back, thank you for the quick response.
This worked exactly as advertised. Thank you so much!
Most helpful comment
This worked exactly as advertised. Thank you so much!