Mercurial > pub > ImplabNet
comparison Implab/Promise.cs @ 96:daffa72a1cec v2
Added the chaining method to the non-generic IPromise
author | cin |
---|---|
date | Thu, 30 Oct 2014 10:06:16 +0300 |
parents | 4f20870d0816 |
children | 8ddf1648eca4 |
comparison
equal
deleted
inserted
replaced
95:0141a165d032 | 96:daffa72a1cec |
---|---|
349 /// <typeparam name="TNew">Новый тип результата.</typeparam> | 349 /// <typeparam name="TNew">Новый тип результата.</typeparam> |
350 /// <param name="mapper">Преобразование результата к новому типу.</param> | 350 /// <param name="mapper">Преобразование результата к новому типу.</param> |
351 /// <param name="error">Обработчик ошибки. Данный обработчик получит | 351 /// <param name="error">Обработчик ошибки. Данный обработчик получит |
352 /// исключение возникшее при выполнении операции.</param> | 352 /// исключение возникшее при выполнении операции.</param> |
353 /// <returns>Новое обещание, которое будет выполнено при выполнении исходного обещания.</returns> | 353 /// <returns>Новое обещание, которое будет выполнено при выполнении исходного обещания.</returns> |
354 /// <param name = "cancel"></param> | |
354 public IPromise<TNew> Then<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler<TNew> error, Action cancel) { | 355 public IPromise<TNew> Then<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler<TNew> error, Action cancel) { |
355 Safe.ArgumentNotNull(mapper, "mapper"); | 356 Safe.ArgumentNotNull(mapper, "mapper"); |
356 | 357 |
357 // создаем прицепленное обещание | 358 // создаем прицепленное обещание |
358 var medium = new Promise<TNew>(this, true); | 359 var medium = new Promise<TNew>(this, true); |
411 /// <typeparam name="TNew">Тип результата указанной асинхронной операции.</typeparam> | 412 /// <typeparam name="TNew">Тип результата указанной асинхронной операции.</typeparam> |
412 /// <param name="chained">Асинхронная операция, которая должна будет начаться после выполнения текущей.</param> | 413 /// <param name="chained">Асинхронная операция, которая должна будет начаться после выполнения текущей.</param> |
413 /// <param name="error">Обработчик ошибки. Данный обработчик получит | 414 /// <param name="error">Обработчик ошибки. Данный обработчик получит |
414 /// исключение возникшее при выполнении текуещй операции.</param> | 415 /// исключение возникшее при выполнении текуещй операции.</param> |
415 /// <returns>Новое обещание, которое будет выполнено по окончанию указанной аснхронной операции.</returns> | 416 /// <returns>Новое обещание, которое будет выполнено по окончанию указанной аснхронной операции.</returns> |
417 /// <param name = "cancel"></param> | |
416 public IPromise<TNew> Chain<TNew>(ResultMapper<T, IPromise<TNew>> chained, ErrorHandler<IPromise<TNew>> error, Action cancel) { | 418 public IPromise<TNew> Chain<TNew>(ResultMapper<T, IPromise<TNew>> chained, ErrorHandler<IPromise<TNew>> error, Action cancel) { |
417 | 419 |
418 Safe.ArgumentNotNull(chained, "chained"); | 420 Safe.ArgumentNotNull(chained, "chained"); |
419 | 421 |
420 // проблема в том, что на момент связывания еще не начата асинхронная операция, поэтому нужно | 422 // проблема в том, что на момент связывания еще не начата асинхронная операция, поэтому нужно |
757 | 759 |
758 #region IPromiseBase explicit implementation | 760 #region IPromiseBase explicit implementation |
759 | 761 |
760 IPromise IPromise.Then(Action success, ErrorHandler error, Action cancel) { | 762 IPromise IPromise.Then(Action success, ErrorHandler error, Action cancel) { |
761 return Then( | 763 return Then( |
762 x => success(), | 764 success != null ? new ResultHandler<T>(x => success()) : null, |
763 e => { | 765 error != null ? new ErrorHandler<T>(e => { |
764 error(e); | 766 error(e); |
765 return default(T); | 767 return default(T); |
766 }, | 768 }) : null, |
767 cancel | 769 cancel |
768 ); | 770 ); |
769 } | 771 } |
770 | 772 |
771 IPromise IPromise.Then(Action success, ErrorHandler error) { | 773 IPromise IPromise.Then(Action success, ErrorHandler error) { |
772 return Then( | 774 return Then( |
773 x => success(), | 775 success != null ? new ResultHandler<T>(x => success()) : null, |
774 e => { | 776 error != null ? new ErrorHandler<T>(e => { |
775 error(e); | 777 error(e); |
776 return default(T); | 778 return default(T); |
777 } | 779 }) : null |
778 ); | 780 ); |
779 } | 781 } |
780 | 782 |
781 IPromise IPromise.Then(Action success) { | 783 IPromise IPromise.Then(Action success) { |
784 Safe.ArgumentNotNull(success, "success"); | |
782 return Then(x => success()); | 785 return Then(x => success()); |
783 } | 786 } |
787 | |
788 IPromise IPromise.Chain(Func<IPromise> chained, ErrorHandler<IPromise> error, Action cancel) { | |
789 return ChainNoResult(chained, error, cancel); | |
790 } | |
791 | |
792 IPromise ChainNoResult(Func<IPromise> chained, ErrorHandler<IPromise> error, Action cancel) { | |
793 Safe.ArgumentNotNull(chained, "chained"); | |
794 | |
795 var medium = new Promise<object>(this, true); | |
796 | |
797 ResultHandler<T> resultHandler = delegate(T result) { | |
798 if (medium.IsCancelled) | |
799 return; | |
800 | |
801 var promise = chained(); | |
802 | |
803 promise.Last( | |
804 medium.Resolve, | |
805 medium.Reject, | |
806 () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка | |
807 ); | |
808 | |
809 // notify chained operation that it's not needed anymore | |
810 // порядок вызова Then, Cancelled важен, поскольку от этого | |
811 // зависит IsExclusive | |
812 medium.Cancelled(() => { | |
813 if (promise.IsExclusive) | |
814 promise.Cancel(); | |
815 }); | |
816 }; | |
817 | |
818 ErrorHandler<T> errorHandler; | |
819 | |
820 if (error != null) | |
821 errorHandler = delegate(Exception e) { | |
822 try { | |
823 var promise = error(e); | |
824 | |
825 promise.Last( | |
826 medium.Resolve, | |
827 medium.Reject, | |
828 () => medium.Reject(new OperationCanceledException()) // внешняя отмена связанной операции рассматривается как ошибка | |
829 ); | |
830 | |
831 // notify chained operation that it's not needed anymore | |
832 // порядок вызова Then, Cancelled важен, поскольку от этого | |
833 // зависит IsExclusive | |
834 medium.Cancelled(() => { | |
835 if (promise.IsExclusive) | |
836 promise.Cancel(); | |
837 }); | |
838 } catch (Exception e2) { | |
839 medium.Reject(e2); | |
840 } | |
841 return default(T); | |
842 }; | |
843 else | |
844 errorHandler = err => { | |
845 medium.Reject(err); | |
846 return default(T); | |
847 }; | |
848 | |
849 | |
850 Action cancelHandler; | |
851 if (cancel != null) | |
852 cancelHandler = () => { | |
853 if (cancel != null) | |
854 cancel(); | |
855 medium.Cancel(); | |
856 }; | |
857 else | |
858 cancelHandler = medium.Cancel; | |
859 | |
860 AddHandler( | |
861 resultHandler, | |
862 errorHandler, | |
863 cancelHandler, | |
864 null | |
865 ); | |
866 | |
867 return medium; | |
868 } | |
869 IPromise IPromise.Chain(Func<IPromise> chained, ErrorHandler<IPromise> error) { | |
870 return ChainNoResult(chained, error, null); | |
871 } | |
872 IPromise IPromise.Chain(Func<IPromise> chained) { | |
873 return ChainNoResult(chained, null, null); | |
874 } | |
875 | |
784 | 876 |
785 void IPromise.Last(Action success, ErrorHandler error, Action cancel) { | 877 void IPromise.Last(Action success, ErrorHandler error, Action cancel) { |
786 Last(x => success(), error, cancel); | 878 Last(x => success(), error, cancel); |
787 } | 879 } |
788 | 880 |