É desejável um sistema de eventos com reconhecimento de promessa?

5

Tenho plena consciência de que Promessas e Eventos são as duas formas de fazer programação assíncrona, e você pode escolher qualquer uma para um determinado projeto. No entanto, na prática, a base de código com a qual estou trabalhando é grande e usamos muitas bibliotecas de terceiros que lidam com a assincronia de maneira diferente, então misturar as duas abordagens juntas é inevitável (e muitas vezes com efeito desastroso).

Muitas vezes vi pessoas dispararem um evento e fazer mais coisas depois dele, enquanto esperavam que os manipuladores de eventos estivessem totalmente concluídos. Infelizmente, alguns manipuladores de eventos iniciarão uma cadeia de promessas, mas não há como a fonte do evento saber quando essa cadeia é resolvida.

Em teoria, a maneira correta de fazer programação assíncrona apenas com eventos puros seria para o manipulador de eventos criar um evento "event_x_completed", mas isso pressupõe que sempre exista exatamente um manipulador de eventos para o "event_x" original (a menos que você quer que o código fique feio. Veja o exemplo na parte inferior). Na programação da interface do usuário, muitas vezes não devemos nos importar com quantos ouvintes existem. Por exemplo. uma ação do usuário poderia gerar um evento para acionar qualquer número de componentes da interface do usuário para atualizar-se.

Além disso, dependendo de como isso é feito, ele pode criar um strong acoplamento entre a origem do evento e os ouvintes do evento, o que invalida uma grande força para usar o evento em primeiro lugar. Meu projeto tem uma interface do usuário complicada, portanto, uma fonte de eventos não pode / não deve se importar com quantos manipuladores estão ouvindo um evento.

Eu acho que seria ótimo ter um sistema de eventos que testa se cada manipulador retorna um Promise (ou objeto capaz), e fire ("event_x") deve retornar Promise.all (all_promises_from_handlers) para a fonte do evento.

Eu olhei ao redor (talvez não o suficiente) e não vejo ninguém falando sobre um sistema de eventos com reconhecimento de promessas. As pessoas têm o mesmo problema e como são tratadas?

Edite para exemplo concreto:

O originador de "SAVE_PRESSED" não se importa com quantos manipuladores existem, apenas preocupa-se que eles estão todos concluídos. Acho que seria imensamente útil poder fazer isso:

function saveClicked() {
    saveButton.disable();
    EventManager.raise("SAVE_PRESSED").then(function() {
        saveButton.enable();
    });
}

Com o evento puro, é claro que poderíamos percorrer todos os ouvintes e fazer isso:

function saveClicked() {
    saveButton.disable();
    var listeners = EventManager.getListeners("SAVE_PRESSED"); // array
    EventManager.raise("SAVE_PRESSED");
    EventManager.listen("SAVE_COMPLETED", function(listener_id) {
        var index = listeners.indexOf(listener_id);
        listeners = listeners.splice(index, 1);
        if (listeners.length === 0) {
            saveButton.enable();
            // AND -- unregister this function as a handler for SAVE_COMPLETED
        }
    });
}

O que eu não gosto sobre isso:

  • O código é mais longo e nem completo e não tem tratamento de erros adequado.
  • Isso depende dos ouvintes que criam um evento "* _COMPLETED".
    • Se isso não for sempre verdadeiro ou obrigatório, cada ouvinte precisará indicar se eles são assíncronos (irão gerar um evento COMPLETED) ou não. Esta é uma configuração adicional para manter.
    • E, em vez de EventManager.getListeners ("SAVE_PRESSED"), chamamos EventManager.getAsyncListeners ("SAVE_PRESSED");
  • Este código / funcionalidade deve ser fornecido pelo EventManager
    • Se for movido para o EventManager, os eventos "* _COMPLETED" serão essencialmente muito especiais .

Em um sistema de eventos com reconhecimento de promessa, os manipuladores podem dizer ao sistema que eles estão assíncronos, simplesmente retornando um objeto então capaz.

    
por RonJRH 19.11.2016 / 02:07
fonte

2 respostas

2

Um sistema de eventos promissor pode ajudá-lo a criar soluções elegantes para problemas complexos. No entanto, acho que vale a pena escolher uma estrutura existente em vez de criar a sua própria.

A estrutura (JavaScript) que mais utilizei é o Dojo e tem uma coleção robusta de código de manipulação de eventos.

Inclui eventos de encadeamento como mencionado, quando e tudo mais. tudo é bom porque vai esperar por um conjunto de promessas para resolver antes de prosseguir.

Sugiro que você leia alguns dos tutoriais em seu site para ver se ele atenderá bem às suas necessidades.

    
por 22.11.2016 / 02:17
fonte
0

In theory, the proper way to do async programming with pure eventing alone would have been for the event handler to raise an "event_x_completed" event but that assumes that there is always exactly one event handler for the original "event_x". In UI programming, we can't make that assumption. E.g. one user action could raise an event to trigger any number of UI components to refresh themselves.

Er não. Você absolutamente não precisa assumir que sempre existe exatamente um manipulador de eventos.

Existem exatamente quantos manipuladores de eventos você deseja. Um manipulador de eventos se registra em uma lista de manipuladores desse evento.

event_x_completed(x_id) me informa exatamente qual evento foi concluído. Não simplesmente que seja um evento do tipo x, mas era exatamente o x que eu estava esperando.

É confuso misturar dois paradigmas diferentes, mas certifique-se de usar ambos antes de assumir que eles são completamente incompatíveis.

    
por 19.11.2016 / 20:52
fonte