/// <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 IFpromise <IEnumerable <FpromisedT> > All(IEnumerable <IFpromise <FpromisedT> > promises) { var promisesArray = promises.ToArray(); if (promisesArray.Length == 0) { return(Fpromise <IEnumerable <FpromisedT> > .Resolved(EnumerableExtensions.Empty <FpromisedT>())); } var remainingCount = promisesArray.Length; var results = new FpromisedT[remainingCount]; var resultFpromise = new Fpromise <IEnumerable <FpromisedT> >(); resultFpromise.WithName("All"); promisesArray.Each((promise, index) => { promise .Catch(ex => { if (resultFpromise.CurState == FpromiseState.Pending) { // If a promise errorred and the result promise is still pending, reject it. resultFpromise.Reject(ex); } }) .Then(result => { results[index] = result; --remainingCount; if (remainingCount <= 0) { // This will never happen if any of the promises errorred. resultFpromise.Resolve(results); } }) .Done(); }); return(resultFpromise); }
/// <summary> /// Return a new promise with a different value. /// May also change the type of the value. /// </summary> public IFpromise <ConvertedT> Transform <ConvertedT>(Func <FpromisedT, ConvertedT> transform) { // Argument.NotNull(() => transform); var resultFpromise = new Fpromise <ConvertedT>(); resultFpromise.WithName(Name); Action <FpromisedT> resolveHandler = v => { resultFpromise.Resolve(transform(v)); }; Action <Exception> rejectHandler = ex => { resultFpromise.Reject(ex); }; ActionHandlers(resultFpromise, resolveHandler, rejectHandler); return(resultFpromise); }
/// <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 IFpromise Race(IEnumerable <IFpromise> promises) { var promisesArray = promises.ToArray(); if (promisesArray.Length == 0) { throw new ApplicationException("At least 1 input promise must be provided for Race"); } var resultFpromise = new Fpromise(); resultFpromise.WithName("Race"); promisesArray.Each((promise, index) => { promise .Catch(ex => { if (resultFpromise.CurState == FpromiseState.Pending) { // If a promise errorred and the result promise is still pending, reject it. resultFpromise.Reject(ex); } }) .Then(() => { if (resultFpromise.CurState == FpromiseState.Pending) { resultFpromise.Resolve(); } }) .Done(); }); return(resultFpromise); }
/// <summary> /// Handle errors for the promise. /// </summary> public IFpromise Catch(Action <Exception> onRejected) { // Argument.NotNull(() => onRejected); var resultFpromise = new Fpromise(); resultFpromise.WithName(Name); Action resolveHandler = () => { resultFpromise.Resolve(); }; Action <Exception> rejectHandler = ex => { onRejected(ex); resultFpromise.Reject(ex); }; ActionHandlers(resultFpromise, resolveHandler, rejectHandler); return(resultFpromise); }