Is there a way to get the effect of RAII using futures that does not rely on memory management schemes. My mental model of how futures work is still developing, so any suggestions on better ways to think about them is appreciated. So when you create a future from scratch you register a function that becomes a list of functions with 1 entry to likely be called and therefore completed at a later time. The then() gives you the ability to chain new functions to be invoked on the end of the list. The whenComplete being like finally allows you to add a function that can be called regardless of success or failure. This sounds promising as a way to manage resources, but the problem is it is triggered immediately after the future it is associated with completes, rather than after all chained thens that may be added. My question is, is there a way to add a function to that list that will always stay at or toward the the end of the list when new then entries are added.
Take this:
import 'dart:async';
p(t) => print(t);
main() {
{
new Future
.sync(() => p('first'))
.whenComplete(() => p('when complete'))
.then((_) => p('second'))
.then((_) => p('third'));
}
}
The list of functions are:
[
() => p('first'),
() => p('when complete'),
() => p('second'),
() => p('third'),
]
An example use for this is you open a database or a file, use it and want client code to use it by tacking on some *thens* and then want to close it automatically without having client code be required to call close. Suppose I want the picture to look like this:
[
() => allocateResource('for first'),
() => p('first'),
() => p('when complete'),
() => allocateResource('for second'),
() => p('second'),
() => p('third'),
() => deallocateResource('for second'),
() => deallocateResource('for first'),
]
The issue is that I want to add the three functions related to first at a single point in time.
new Future
.thenBlock(open: allocateResource('for first'),
close: deallocateResource('for first),
then: () => p('first'))
.whenComplete(() => p('when complete'))
.thenBlock(open: allocateResource('for second'),
close: deallocateResource('for second'),
then: () => p('second'))
.then((_) => p('third'));
Effectively it would be nice to allow third, fourth, ... infinite to jump the queue and keep pushing the deallocation methods back until they are known not to be needed. The benefit is the chain of functions that require the resources determines the lifespan of the resources.
- Does this make sense?
- Is this feasible?
- Are there already existing ways to achieve this?
void withFile(String path, void callback(RandomAccessFile file)) {var file = new File(path).openSync();try {callback(file);} finally {file.close();}}
Future withFile(String path, Future callback(RandomAccessFile file)) {return new File(path).open().then(callback).whenComplete(() {file.close();});}
Future withFile(String path, Future callback(RandomAccessFile file)) async {var file = await new File(path).open();try {await callback(file);} finally {file.close();}}
Cheers!- bob
Will there ever be an automatic resource management mechanism in Dart? Like the Java try() or C# using() syntax.
--
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to http://www.dartbug.com/new