/// <summary> /// Returns a promise that resolves when all of the promises in the enumerable argument have resolved. /// Returns a promise of a collection of the resolved results. /// </summary> public static IPromise All(IEnumerable <IPromise> promises) { var promisesArray = promises.ToArray(); if (promisesArray.Length == 0) { return(Promise.Resolved()); } var remainingCount = promisesArray.Length; var resultPromise = new Promise(); resultPromise.WithName("All"); promisesArray.Each((promise, index) => { promise .Catch(ex => { if (resultPromise.CurState == PromiseState.Pending) { // If a promise errorred and the result promise is still pending, reject it. resultPromise.Reject(ex); } }) .Then(() => { --remainingCount; if (remainingCount <= 0) { // This will never happen if any of the promises errorred. resultPromise.Resolve(); } }) .Done(); }); return(resultPromise); }
/// <summary> /// Return a new promise with a different value. /// May also change the type of the value. /// </summary> public IPromise <ConvertedT> Transform <ConvertedT>(Func <PromisedT, ConvertedT> transform) { Argument.NotNull(() => transform); var resultPromise = new Promise <ConvertedT>(); resultPromise.WithName(Name); Action <PromisedT> resolveHandler = v => { resultPromise.Resolve(transform(v)); }; Action <Exception> rejectHandler = ex => { resultPromise.Reject(ex); }; ActionHandlers(resultPromise, resolveHandler, rejectHandler); return(resultPromise); }
/// <summary> /// Add a resolved callback and a rejected callback. /// The resolved callback chains a non-value promise. /// </summary> public IPromise Then(Func <IPromise> onResolved, Action <Exception> onRejected) { var resultPromise = new Promise(); resultPromise.WithName(Name); Action resolveHandler = () => { if (onResolved != null) { onResolved() .Then( () => resultPromise.Resolve(), ex => resultPromise.Reject(ex) ) .Done(); } else { resultPromise.Resolve(); } }; Action <Exception> rejectHandler = ex => { if (onRejected != null) { onRejected(ex); } resultPromise.Reject(ex); }; ActionHandlers(resultPromise, resolveHandler, rejectHandler); return(resultPromise); }
/// <summary> /// Returns a promise that resolves when the first of the promises in the enumerable argument have resolved. /// Returns the value from the first promise that has resolved. /// </summary> public static IPromise Race(IEnumerable <IPromise> promises) { var promisesArray = promises.ToArray(); if (promisesArray.Length == 0) { throw new ApplicationException("At least 1 input promise must be provided for Race"); } var resultPromise = new Promise(); resultPromise.WithName("Race"); promisesArray.Each((promise, index) => { promise .Catch(ex => { if (resultPromise.CurState == PromiseState.Pending) { // If a promise errorred and the result promise is still pending, reject it. resultPromise.Reject(ex); } }) .Then(() => { if (resultPromise.CurState == PromiseState.Pending) { resultPromise.Resolve(); } }) .Done(); }); return(resultPromise); }
/// <summary> /// Handle errors for the promise. /// </summary> public IPromise Catch(Action <Exception> onRejected) { Argument.NotNull(() => onRejected); var resultPromise = new Promise(); resultPromise.WithName(Name); Action resolveHandler = () => { resultPromise.Resolve(); }; Action <Exception> rejectHandler = ex => { onRejected(ex); resultPromise.Reject(ex); }; ActionHandlers(resultPromise, resolveHandler, rejectHandler); return(resultPromise); }