view Implab/PromiseT.cs @ 196:40d7fed4a09e

fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
author cin
date Mon, 29 Aug 2016 23:15:51 +0300
parents e03ccec4a08d
children 4d9830a9bbb8
line wrap: on
line source

using System;
using System.Diagnostics;
using Implab.Parallels;

namespace Implab {

    /// <summary>
    /// Класс для асинхронного получения результатов. Так называемое "обещание".
    /// </summary>
    /// <typeparam name="T">Тип получаемого результата</typeparam>
    /// <remarks>
    /// <para>Сервис при обращении к его методу дает обещаиние о выполнении операции,
    /// клиент получив такое обещание может установить ряд обратных вызово для получения
    /// событий выполнения обещания, тоесть завершения операции и предоставлении результатов.</para>
    /// <para>
    /// Обещение может быть как выполнено, так и выполнено с ошибкой. Для подписки на
    /// данные события клиент должен использовать методы <c>Then</c>.
    /// </para>
    /// <para>
    /// Сервис, в свою очередь, по окончанию выполнения операции (возможно с ошибкой),
    /// использует методы <c>Resolve</c> либо <c>Reject</c> для оповещения клиетна о
    /// выполнении обещания.
    /// </para>
    /// <para>
    /// Если сервер успел выполнить обещание еще до того, как клиент на него подписался,
    /// то в момент подписки клиента будут вызваны соответсвующие события в синхронном
    /// режиме и клиент будет оповещен в любом случае. Иначе, обработчики добавляются в
    /// список в порядке подписания и в этом же порядке они будут вызваны при выполнении
    /// обещания.
    /// </para>
    /// <para>
    /// Обрабатывая результаты обещания можно преобразовывать результаты либо инициировать
    /// связанные асинхронные операции, которые также возвращают обещания. Для этого следует
    /// использовать соответствующую форму методе <c>Then</c>.
    /// </para>
    /// <para>
    /// Также хорошим правилом является то, что <c>Resolve</c> и <c>Reject</c> должен вызывать
    /// только инициатор обещания иначе могут возникнуть противоречия.
    /// </para>
    /// </remarks>
    public class Promise<T> : AbstractPromise<T>, IDeferred<T> {

        public static IPromise<T> FromResult(T value) {
            return new SuccessPromise<T>(value);
        }

        public static IPromise<T> FromException(Exception error) {
            var p = new Promise<T>();
            p.Reject(error);
            return p;
        }

        public virtual void Resolve(T value) {
            SetResult(value);
        }

        public void Reject(Exception error) {
            SetError(error);
        }
    }
}