using System.Collections.Generic;
public static void Main()
Action<string> callbackThatWillUseTheResolvedString = Console.WriteLine;
Action<string> callbackWithAHardCodedString = i => Console.WriteLine("Here is the hard coded string.");
var callbackList = new List<Action<string>>
callbackThatWillUseTheResolvedString, callbackWithAHardCodedString
var deferred = new Deferred<string>();
var promise = deferred.Promise();
promise.Done(callbackList);
promise.Fail(i => Console.WriteLine(i));
promise.Always(() => Console.WriteLine("Finished."));
deferred.Resolve("This string was passed into the resolved method.");
Promise Done(Action callback);
Promise Fail(Action callback);
Promise Always(Action callback);
public interface Promise<T> : Promise
Promise<T> Done(Action<T> callback);
Promise<T> Done(IEnumerable<Action<T>> callbacks);
Promise<T> Fail(Action<T> callback);
Promise<T> Fail(IEnumerable<Action<T>> callbacks);
Promise<T> Always(Action<T> callback);
Promise<T> Always(IEnumerable<Action<T>> callbacks);
public class Deferred : Deferred<object>
public class Deferred<T> : Promise<T>
private List<Callback> callbacks = new List<Callback>();
protected bool _isResolved = false;
protected bool _isRejected = false;
public static Promise When(IEnumerable<Promise> promises)
var masterPromise = new Deferred();
foreach (var p in promises)
public static Promise When(object d)
var masterPromise = new Deferred();
public static Promise When(Deferred d)
public static Promise<T> When(Deferred<T> d)
public Promise<T> Promise()
public Promise Always(Action callback)
if (_isResolved || _isRejected)
callbacks.Add(new Callback(callback, Callback.Condition.Always, false));
public Promise<T> Always(Action<T> callback)
if (_isResolved || _isRejected)
callbacks.Add(new Callback(callback, Callback.Condition.Always, true));
public Promise<T> Always(IEnumerable<Action<T>> callbacks)
foreach (Action<T> callback in callbacks)
public Promise Done(Action callback)
callbacks.Add(new Callback(callback, Callback.Condition.Success, false));
public Promise<T> Done(Action<T> callback)
callbacks.Add(new Callback(callback, Callback.Condition.Success, true));
public Promise<T> Done(IEnumerable<Action<T>> callbacks)
foreach (Action<T> callback in callbacks)
public Promise Fail(Action callback)
callbacks.Add(new Callback(callback, Callback.Condition.Fail, false));
public Promise<T> Fail(Action<T> callback)
callbacks.Add(new Callback(callback, Callback.Condition.Fail, true));
public Promise<T> Fail(IEnumerable<Action<T>> callbacks)
foreach (Action<T> callback in callbacks)
return _isRejected || _isResolved;
if (_isRejected || _isResolved)
DequeueCallbacks(Callback.Condition.Fail);
public Deferred<T> Reject(T arg)
if (_isRejected || _isResolved)
DequeueCallbacks(Callback.Condition.Fail);
if (_isRejected || _isResolved)
DequeueCallbacks(Callback.Condition.Success);
public Deferred<T> Resolve(T arg)
if (_isRejected || _isResolved)
DequeueCallbacks(Callback.Condition.Success);
private void DequeueCallbacks(Callback.Condition cond)
foreach (Callback callback in callbacks)
if (callback.Cond == cond || callback.Cond == Callback.Condition.Always)
if (callback.IsReturnValue)
callback.Del.DynamicInvoke(_arg);
callback.Del.DynamicInvoke();
public Callback(Delegate del, Condition cond, bool returnValue)
IsReturnValue = returnValue;
public bool IsReturnValue