Question

How I can return Future value from Future object? This code does not work.

import 'dart:async';

    void main() {
      var temp = foo();
      temp.then((Future<int> future) {
        future.then((int result) {
          print(result);
        });
      });
    }

    Future<Future<int>> foo() {
      return new Future<Future<int>>(() {
        return new Future<int>(() => 5);
      });
    }

How to prevent unnecessary unwrapping?

In this case in async library 'Future' declared as generic class.

abstract class Future<T> {
}

If I create expression as the following

new Future<Future<int>>();

Then with type T specified as Future<int> which result expected from generic class Future?

I thing that result must be as specified in type argument T.

I.e. Future<int>.

But result is not as expected. There is no information found about this abnormal behavior on Dart API site.

If this is a "feature" (but I think that abnormal behavior wrongly to call "feature') then why it not documented in Dart API?

How can be explained this discrepancy?

Why this code not generated errors and warnings?

Another IDENTICAL example but w/o using Future.

void main() {
  var temp = foo();
  temp.baz((Foo<int> foo) {
    foo.baz((int result) {
      print(result);
    });
  });
}

Foo<Foo<int>> foo() {
  return new Foo<Foo<int>>(() {
    return new Foo<int>(() => 5);
  });
}

If in this case result will be as when using Future (i.e. unexpected) then how we can call this code? Normal or abnormal?

Or maybe the Future in Dart some special (magic)?

Was it helpful?

Solution

Look at the api documentation http://api.dartlang.org/docs/releases/latest/dart_async/Future.html

It says there:

If the returned value is itself a Future, completion of the created future will wait until
the returned future completes, and will then complete with the same result.

I guess that means you can't return a Future from a Future. But you could return a list of futures.

void main() {
  var temp = foo();
  temp.then((List<Future<int>> list) {
    list[0].then((int result) {
      print(result);
    });
  });
}

Future<List<Future<int>>> foo() {
  return new Future<List<Future<int>>>(() {
    return [new Future<int>(() => 5)];
  });
}

OTHER TIPS

There is no need for any of that extra wrapping. According to the Future documentation:

If the returned value is itself a [Future], completion of the created future will wait until the returned future completes, and will then complete with the same result.

This means you can rewrite your code as:

import 'dart:async';

void main() {
  var temp = foo();
  temp.then((int result) {
    print(result);        
  });
}

Future<int> foo() {
  return new Future<int>(() {
    return new Future<int>(() => 5);
  });
}

This is a lot cleaner to work with and provides the expected result.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top