blob: 8b429dc69b183e3e52621a5102af5605b44372ab [file] [log] [blame]
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library when;
import 'dart:async';
/// Registers callbacks on the result of a [callback], which may or may not be
/// a [Future].
///
/// If [callback] returns a future, any of [onSuccess], [onError], or
/// [onComplete] that are provided are registered on the future,
/// and the resulting future is returned.
///
/// Otherwise, if [callback] did not throw, if [onSuccess] is provided, it is
/// called with the with the result of [callback], and the return value of
/// [onSuccess] is captured.
///
/// Otherwise, if [onError] was provided, it is called. It can take either
/// just an error, or a stack trace as well. If [onError] was not provided,
/// the error is not caught.
///
/// [onComplete] is then called synchronously.
///
/// The captured value is then returned.
when(callback, {onSuccess(result), onError, onComplete}) {
var result, hasResult = false;
try {
result = callback();
hasResult = true;
} catch (e, s) {
if (onError != null) {
if (onError is _Unary) {
onError(e);
} else if (onError is _Binary) {
onError(e, s);
} else {
throw new ArgumentError(
'"onError" must accept 1 or 2 arguments: $onError');
}
} else {
rethrow;
}
} finally {
if (result is Future) {
if (onSuccess != null) {
result = result.then(onSuccess);
}
if (onError != null) {
result = result.catchError(onError);
}
if (onComplete != null) {
result = result.whenComplete(onComplete);
}
} else {
if (hasResult) {
if (onSuccess != null) {
result = onSuccess(result);
}
}
if (onComplete != null) onComplete();
}
}
return result;
}
typedef _Unary(x);
typedef _Binary(x, y);