Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need async versions of reduce() and mappedBy() #8170

Closed
justinfagnani opened this issue Jan 29, 2013 · 6 comments
Closed

Need async versions of reduce() and mappedBy() #8170

justinfagnani opened this issue Jan 29, 2013 · 6 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. closed-obsolete Closed as the reported issue is no longer relevant core-n P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug

Comments

@justinfagnani
Copy link
Contributor

I needed to run an async function on every element of an Iterable where each invocation needed the result of the previous, and so had to wait on a Future, very much like an async reduce(). This could be included in dart:async.

Here's what I wrote:

    /**
     * Similar to [Iterable.reduce], except that [combine] is an async function
     * that returns a [Future].
     */
    Future reduceAsync(Iterable iterable, initialValue, combine(previous, element))
        => _reduceAsync(iterable.iterator, initialValue, combine);

    Future _reduceAsync(Iterator iterator, currentValue, combine(previous, element)) {
      if (iterator.moveNext()) {
        return combine(currentValue, iterator.current).then((result) =>
            _reduceAsync(iterator, result, combine));
      }
      return new Future.immediate(currentValue);
    }

@floitschG
Copy link
Contributor

cc @lrhn.

@DartBot
Copy link

DartBot commented Jan 29, 2013

This comment was originally written by @seaneagan


Maybe add an optional parameter to Stream.fromIterable to lazily convert each element of the iterable to a Future whose result becomes a data event in the Stream:

Stream<T>.fromIterable(Iterable iterable, [T process(element)]);

then could just use Stream.reduce:

new Stream<Foo>.fromIterable(iterable, toFoo).reduce(combine);

@floitschG
Copy link
Contributor

What we still miss is a way to start asynchronous actions in event handlers and keep the output order. Something like:
new Stream<Foo>.fromIterable(iterable)
  .asyncMap((data) => asyncOperation(data)) // returns a future.
  .reduce(combine);

This would basically launch all asyncOperations in parallel, and then reduce them sequentially as soon as they are available.

@DartBot
Copy link

DartBot commented Jan 29, 2013

This comment was originally written by @seaneagan


A Stream doesn't know it's events up front, so I don't think it can launch all the asyncOperations in parallel. Also, many operations on a Stream don't need all the events, so that might be wasteful. I think issue #6626 aims to solve parallel async operations.

Of course I meant for "process" to return a Future above:

Stream<T>.fromIterable(Iterable iterable, [Future<T> process(element)]);

@justinfagnani
Copy link
Contributor Author

To clarify for my use in this case, I can't separate the operation into an async part that can be done out-of-order and a sync reduce step that is done in order. Each async operation depends on the output of the previous async operation, so they must be chained. This might be more accurately described as a left async fold.

There are a bunch of possible variations here. Whether the map or reduce steps exist, whether they are sync or async, whether reduce is associative, and whether reduce is symmetric (or needs a seed value). All of this could be covered by map, reduce, asyncMap and asyncReduce with options on asyncMap and asyncReduce that specify the ordering.

@DartBot
Copy link

DartBot commented May 22, 2014

This comment was originally written by @seaneagan


asyncMap and asyncExpand now exist. This can be merged with issue #18331 which covers any further methods.

@justinfagnani justinfagnani added Type-Enhancement area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. labels May 22, 2014
@kevmoo kevmoo added P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug and removed triaged labels Feb 29, 2016
@lrhn lrhn added the core-m label Aug 11, 2017
@floitschG floitschG added core-n and removed core-m labels Aug 29, 2017
@matanlurey matanlurey added the closed-obsolete Closed as the reported issue is no longer relevant label Jun 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. closed-obsolete Closed as the reported issue is no longer relevant core-n P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

6 participants