Why would one use the Publish/Subscribe pattern (in JS/jQuery)?

前端 未结 7 426
无人及你
无人及你 2020-11-30 16:25

So, a colleague introduced me to the publish/subscribe pattern (in JS/jQuery), but I\'m having a hard time getting to grips with why one would use this pattern over

7条回答
  •  攒了一身酷
    2020-11-30 16:37

    The other answers have done a great job in showing how the pattern works. I wanted to address the implied question "what is wrong with the old way?" as I've been working with this pattern recently, and I find it involves a shift in my thinking.

    Imagine we have subscribed to an economic bulletin. The bulletin publishes a headline: "Lower the Dow Jones by 200 points". That would be an odd and somewhat irresponsible message to send. If however, it published: "Enron filed for chapter 11 bankrupcy protection this morning", then this is a more useful message. Note that the message may cause the Dow Jones to fall 200 points, but that is another matter.

    There is a difference between sending a command, and advising of something that has just happened. With this in mind, take your original version of the pub/sub pattern, ignoring the handler for now:

    $.subscribe('iquery/action/remove-order', removeOrder);
    
    $container.on('click', '.remove_order', function(event) {
        event.preventDefault();
        $.publish('iquery/action/remove-order', $(this).parents('form:first').find('div.order'));
    });
    

    There is already an implied strong coupling here, between the user-action (a click) and the system-response (an order being removed). Effeectively in your example, the action is giving a command. Consider this version:

    $.subscribe('iquery/action/remove-order-requested', handleRemoveOrderRequest);
    
    $container.on('click', '.remove_order', function(event) {
        event.preventDefault();
        $.publish('iquery/action/remove-order-requested', $(this).parents('form:first').find('div.order'));
    });
    

    Now the handler is responding to something of interest that has happened, but is under no obligation to remove an order. In fact, the handler can do all sorts of things not directly related to removing an order, but still maybe relevant to the calling action. For example:

    handleRemoveOrderRequest = function(e, orders) {
        logAction(e, "remove order requested");
        if( !isUserLoggedIn()) {
            adviseUser("You need to be logged in to remove orders");
        } else if (isOkToRemoveOrders(orders)) {
            orders.last().remove();
            adviseUser("Your last order has been removed");
            logAction(e, "order removed OK");
        } else {
            adviseUser("Your order was not removed");
            logAction(e, "order not removed");
        }
        remindUserToFloss();
        increaseProgrammerBrowniePoints();
        //etc...
    }
    

    The distinction between a command and a notification is a useful distinction to make with this pattern, IMO.

提交回复
热议问题