Цепочки Promise

Для упрощения задач обработки результатов асинхронных операций библиотека предоставляет вспомогательные классы для создание "цепочек" Promise. Под цепочкой подразумевается Promise, который преобразует результат выполнения предшествующего ему Promise (например, последовательность "сделать HTTP-запрос -> декодировать JSON - обработать результат).

Этими вспомогательными классами является семейство классов MBSL_PromiseChain (MBSL_PromiseChain, MBSL_PromiseChain_ToRef, MBSL_PromiseChain_FromRef, MBSL_PromiseChain_FromRefToRef). Каждый класс позволяет сформировать "цепочку", получая "исходный" Promise и создавая "зависимый" Promise.

Главным отличием этих классов являются типы Promise, с которыми они работаю - MBSL_Promise или MBSL_PromiseRef. Классы с "FromRef" в названии принимаю в качестве "исходного" тип MBSL_PromiseRef, без - MBSL_Promise. Классы с "ToRef" в названии создают в качестве "зависимого" тип MBSL_PromiseRef, без - MBSL_Promise.

//PrevResultType - тип результата "родительского" Promise
//NextResultType - тип результата "зависимого" Promise 
class MBSL_PromiseChain<Class PrevResultType, Class NextResultType> : Managed
{
	//Создать цепочку Promise с асинхронным обработчиком
	static MBSL_Promise<NextResultType> Create(MBSL_Promise<PrevResultType> promise, MBSL_TypedFunction1<MBSL_Promise<NextResultType>, PrevResultType> handler);
	//Создать цепочку Promise с синхронным обработчиком
	static MBSL_Promise<NextResultType> Create(MBSL_Promise<PrevResultType> promise, MBSL_TypedFunction1<NextResultType, PrevResultType> handler);
}

При создании цепочки можно указать два вида обработчика - синхронный и асинхронный. Принцип работы цепочки значительно отличаться не будет:

  1. Цепочка ожидает разрешения "родительского" Promise:

    1. Если "родительский" Promise был отклонён, то "зависимый" Promise отклоняется и вызов обработчика пропускается.

    2. Если "родительский" Promise был выполнен, то вызывается обработчик.

  2. В зависимости от типа обработчика:

    1. Если обработчик синхронный, то "зависимый" Promise выполняется с результатом обработчика.

    2. Если обработчик асинхронный, то он создаёт "промежуточный" Promise.

  3. Цепочка ожидает разрешения "промежуточного" Promise:

    1. Если "промежуточный" Promise был отклонён, то "зависимый" Promise отклоняется.

    2. Если "промежуточный" Promise был выполнен, то "зависимый" Promise выполняется с тем же результатом.

Пример использования цепочки:

class Example : Managed
{
    MBSL_Promise<string> GET(RestContext ctx, string url, int attempts = 5);
    
    ref MBSL_TypedFunction1<MBSL_PromiseRef<MBSL_JsonObject>, string> _Parse = MBSL_TypedFunction1<MBSL_PromiseRef<MBSL_JsonObject>, string>.Weak(this, "Parse");
    MBSL_PromiseRef<MBSL_JsonObject> Parse(string value);
    
    ref MBSL_TypedAction1<MBSL_JsonObject> _PrintIt = MBSL_TypedAction1<MBSL_JsonObject>.Weak(this, "PrintIt");
    void PrintIt(MBSL_JsonObject obj)
    {
        Print(obj.GetString("it"));
    } 
}

RestContext ctx = GetRestApi().GetRestContext("https://api.com");
Example e = new Example();
//Совершаем запрос к API, которое возвращает JSON
MBSL_Promise<string> req = e.GET(ctx, "/get_json");
//Создаём цепочку, чтобы когда запрос будет завершён, начать парсить JSON
MBSL_PromiseRef<MBSL_JsonObject> json = MBSL_PromiseChain_ToRef<string, MBSL_JsonObject>.Create(req, e._Parse.AsStrong());
//Когда JSON распрашен, выполняем полезную нагрузку с ним
json.WhenFulfilled(e._PrintIt);

Last updated