@@ -31,6 +31,10 namespace Implab { | |||
|
31 | 31 | IPromise Then(Action success, ErrorHandler error); |
|
32 | 32 | IPromise Then(Action success); |
|
33 | 33 | |
|
34 | IPromise Chain(Func<IPromise> chained, ErrorHandler<IPromise> error, Action cancel); | |
|
35 | IPromise Chain(Func<IPromise> chained, ErrorHandler<IPromise> error); | |
|
36 | IPromise Chain(Func<IPromise> chained); | |
|
37 | ||
|
34 | 38 | /// <summary> |
|
35 | 39 | /// Добавляет последнй обработчик в цепочку обещаний, не создает промежуточных обещаний. |
|
36 | 40 | /// </summary> |
@@ -351,6 +351,7 namespace Implab { | |||
|
351 | 351 | /// <param name="error">Обработчик ошибки. Данный обработчик получит |
|
352 | 352 | /// исключение возникшее при выполнении операции.</param> |
|
353 | 353 | /// <returns>Новое обещание, которое будет выполнено при выполнении исходного обещания.</returns> |
|
354 | /// <param name = "cancel"></param> | |
|
354 | 355 | public IPromise<TNew> Then<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler<TNew> error, Action cancel) { |
|
355 | 356 | Safe.ArgumentNotNull(mapper, "mapper"); |
|
356 | 357 | |
@@ -413,6 +414,7 namespace Implab { | |||
|
413 | 414 | /// <param name="error">Обработчик ошибки. Данный обработчик получит |
|
414 | 415 | /// исключение возникшее при выполнении текуещй операции.</param> |
|
415 | 416 | /// <returns>Новое обещание, которое будет выполнено по окончанию указанной аснхронной операции.</returns> |
|
417 | /// <param name = "cancel"></param> | |
|
416 | 418 | public IPromise<TNew> Chain<TNew>(ResultMapper<T, IPromise<TNew>> chained, ErrorHandler<IPromise<TNew>> error, Action cancel) { |
|
417 | 419 | |
|
418 | 420 | Safe.ArgumentNotNull(chained, "chained"); |
@@ -759,29 +761,119 namespace Implab { | |||
|
759 | 761 | |
|
760 | 762 | IPromise IPromise.Then(Action success, ErrorHandler error, Action cancel) { |
|
761 | 763 | return Then( |
|
762 | x => success(), | |
|
763 | e => { | |
|
764 | success != null ? new ResultHandler<T>(x => success()) : null, | |
|
765 | error != null ? new ErrorHandler<T>(e => { | |
|
764 | 766 | error(e); |
|
765 | 767 | return default(T); |
|
766 | }, | |
|
768 | }) : null, | |
|
767 | 769 | cancel |
|
768 | 770 | ); |
|
769 | 771 | } |
|
770 | 772 | |
|
771 | 773 | IPromise IPromise.Then(Action success, ErrorHandler error) { |
|
772 | 774 | return Then( |
|
773 | x => success(), | |
|
774 | e => { | |
|
775 | success != null ? new ResultHandler<T>(x => success()) : null, | |
|
776 | error != null ? new ErrorHandler<T>(e => { | |
|
775 | 777 | error(e); |
|
776 | 778 | return default(T); |
|
777 | } | |
|
779 | }) : null | |
|
778 | 780 | ); |
|
779 | 781 | } |
|
780 | 782 | |
|
781 | 783 | IPromise IPromise.Then(Action success) { |
|
784 | Safe.ArgumentNotNull(success, "success"); | |
|
782 | 785 | return Then(x => success()); |
|
783 | 786 | } |
|
784 | 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 | ||
|
876 | ||
|
785 | 877 | void IPromise.Last(Action success, ErrorHandler error, Action cancel) { |
|
786 | 878 | Last(x => success(), error, cancel); |
|
787 | 879 | } |
General Comments 0
You need to be logged in to leave comments.
Login now