What’s the difference between "Future.whenComplete" and "Future.then"?

Asked

Viewed 752 times

5

The Dart language provides several mechanisms for handling asynchronous calls. One I’m very used to is modifying await, which can be used in functions marked as async.

However, we are sometimes in a function that is not marked as asynchronous, and in such cases we are presented to class objects Future. This class has some methods that I can point out as callbacks:

  • then()
  • whenComplete()
  • catchError()

The context documentation that VS Code provides on the catchErro() me is very clear (free translation):

Manipulates errors made by it Future

But I was confused about the use of then() and that of whenComplete(). About then():

Registers callbacks to be called when this Future complete

And the whenComplete():

Records a function to be called when it Future complete

Then my question remains:

  • what is the difference between the two methods?
  • what is the classic case of then()? what is the classic case of whenComplete()?

1 answer

3


The whenComplete is simply called when the Future is completed: when the value that the Future redeems is finally obtained. Note that the function passed has no arguments, is a simple knowing that the Future completed.

For example, using the sqflite, we have the option to call the method Database.rawInsert, that returns a id on the amendment.

If, by any chance, I’m only interested know that the consultation has been completed (for good or for evil), I can do the following:

Database db = ...;

Future<dynamic> insercao = db.rawInsert("INSERT (a, b) INTO TABLE values ('valor', 'outro valor')");

insercao.whenComplete(() => print('o futuro chegou!'));

Already the then allows you intertwines with the future or, even more, alter the future returned.

De volta para o futuro

For example, I may have a query that returns multiple elements, but I’m only interested in the first:

Database db = ...;

Future<Map<String, dynamic>> primeiroDado = db.rawQuery('SELECT * FROM TABLE).then((l) => l.first);

Note that the returned future is no longer a list of maps, but simply a single map. This transformation was done using the then() and can be done in synchronous parts of the code.

If you are working on asynchronous functions, it is more natural to use a T myValue = await myFuture and work on top of myValue. In the above examples:

// no lugar do whenComplete()
Database db = ...;

await db.rawInsert("INSERT (a, b) INTO TABLE values ('valor', 'outro valor')");

print('o futuro chegou!');

// no lugar do then()

Database db = ...;

Map<String, dynamic> primeiroDado = (await db.rawQuery('SELECT * FROM TABLE)).first;

Soon I shall rise to a more natural use of these functions.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.