when 0.2.0
when: ^0.2.0 copied to clipboard
Register callbacks on code which is conditionally sync or async.
when
#
It's often useful to provide sync (convenient) and async (concurrent) versions
of the same API. dart:io does this with many APIs including Process.run
and Process.runSync. Since the sync and async versions do the same thing,
much of the logic is the same, with just a few small bits differing in their
sync vs. async implementation.
The when function allows for registering onSuccess, onError, and
onComplete callbacks on another callback which represents that sync/async
dependent part of the API. If the callback is sync (returns a non-Future or
throws), then the other callbacks are invoked synchronously, otherwise the
other callbacks are registered on the returned Future.
For example, here's how it can be used to implement sync and async APIs for reading a JSON data structure from the file system with file absence handling:
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:when/when.dart';
/// Reads and decodes JSON from [path] asynchronously.
///
/// If [path] does not exist, returns the result of calling [onAbsent].
Future readJsonFile(String path, {onAbsent()}) => _readJsonFile(
path, onAbsent, (file) => file.exists(), (file) => file.readAsString());
/// Reads and decodes JSON from [path] synchronously.
///
/// If [path] does not exist, returns the result of calling [onAbsent].
readJsonFileSync(String path, {onAbsent()}) => _readJsonFile(
path, onAbsent, (file) => file.existsSync(),
(file) => file.readAsStringSync());
_readJsonFile(String path, onAbsent(), exists(File file), read(File file)) {
var file = new File(path);
return when(
() => exists(file),
onSuccess: (doesExist) => doesExist ?
when(() => read(file), onSuccess: JSON.decode) :
onAbsent());
}
main() {
var syncJson = readJsonFileSync('foo.json', onAbsent: () => {'foo': 'bar'});
print('Sync json: $syncJson');
readJsonFile('foo.json', onAbsent: () => {'foo': 'bar'}).then((asyncJson) {
print('Async json: $asyncJson');
});
}