In Dart, if I use Future.wait with a list of Futur

2020-06-20 04:47发布

问题:

If I have the following code:

Future<int> a = new Future(() { print('a'); return 1; });
Future<int> b = new Future.error('Error!');
Future<int> c = new Future(() { print('c'); return 3; });

Future.wait([a, b, c])
  .then((List<int> values) => print(values))
  .catchError((e) => print(e));

What is printed?

Does the error caught by catchError have any idea of what Future died? Or which Futures remain?

回答1:

Determining what is printed is pretty easy by running it (do you not have a Dart VM handy?):

a
c
AsyncError: 'Error!'

The documentation for Future.wait() says:

Wait for all the given futures to complete and collect their values.

Returns a future which will complete once all the futures in a list are complete. If any of the futures in the list completes with an error, the resulting future also completes with an error. Otherwise the value of the returned future will be a list of all the values that were produced.

e.error is the value that was created with ('Error!', in this case), so by setting that to something indicating which Future has the error, you can see which Future "died". Of course, if you're not the one creating the error, that doesn't help.

In general, I think you use Future.wait() on a List like this when an error in any of them would be handled similarly. Needing to know which one failed might be a sign that you don't want to wait() on all of them together.

Update: I just realized the question title asks a question not asked in the question body: What happens to the other Futures?

The other Futures keep running. The Future returned by wait() throws whichever error it receives as soon as it receives it, so all return values are lost, and if any of the other Futures throws an error, it isn't caught, but each Future still runs until returning or throwing an error.



回答2:

AFAIK, you won't know precisely which Future generated the error. But, you can query the error object and get some useful information:

Future.wait([a, b, c])
.then((List<int> values) => print(values))
.catchError((e) {
  print(e.error);
  print(e.stackTrace);
  print(e.runtimeType);
  print(e.error.runtimeType);
});

Running this prints:

a
c
Error!
null
AsyncError
String

This tells us that the original error was a String. I don't know how useful that is to you, but its something.



标签: dart