| @@ -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
