Werex Zenok
Werex Zenok

Reputation: 143

How can I asynchronously stream loaded objects from a list of futures in Dart

I have a list of objects that can be loaded by calling the function object.load(). This function returns a loaded version of the same object asynchronously. I want call the load() funcion of all objects in a list at the same time and stream the loaded versions as soon as they finish loading. The code below works but the program is loading one object at a time.

Sender:

Stream<ImageIconModel> streamLoadedIcons() async* {
    for (var i = 0; i < imageIconModels.length; i++) {
      yield await imageIconModels[i].load().then((loadedIconModel) {
        return loadedIconModel;
      });
    }
  }

Receiver:

    await for (var loadedIcon in streamLoadedIcons()) {
     final var result = doSomething(loadedIcon);
     yield result;
    }

The main problem is: In the sender, if I await each load() call, it will do every step in the loop awaiting the load() to finish. But if I remove the "await", I would be returning a future, not the loaded icon.

Upvotes: 0

Views: 636

Answers (2)

Werex Zenok
Werex Zenok

Reputation: 143

Both @hacker1024 an @pskink answers successfully answered my question! But neither one worked as it supposed to and I think I discovered why.

I substituted the load() method for a Future.delayed(duration: random), and then the program worked as it intended to.

So what I think happened is that probably the lib I'm using to load the images (multi_image_picker: ^4.7.14) is accessing the phone files synchronously. So even if I try to load every image at same time, it will do the task synchronously and return every image at the order I called them to load.

Thank you both for the answer!

Upvotes: 0

hacker1024
hacker1024

Reputation: 3668

You need Stream.fromFutures.

final loadedIconModelStream = Stream.fromFutures([
  for (final iconModel in imageIconModels) iconModel.load(),
]);

Upvotes: 1

Related Questions