publish/subscribe pattern

In this example below you will see how to do a publish/subscribe pattern with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by River-Wood, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright River-Wood ©
  • HTML
  • CSS
  • JavaScript
    

/*Downloaded from https://www.codeseek.co/River-Wood/publishsubscribe-pattern-aVWQYm */
    


/*Downloaded from https://www.codeseek.co/River-Wood/publishsubscribe-pattern-aVWQYm */
    var myObj = {};

//subscribe pattern
//is a object
//which has
//subscribe unsubscribe public functions
//that able to create a custom event listener.
//IFFE used to enchaing target obj
(function(enhancingObj){
  var topics = new Map();
  var uniqueId = -1;
  
  function TokenRecord({
    func,
    token
  }){
    this.func = func;
    this.token = token;
    return this;
  }
  
  TokenRecord.of = function({
    func,
    token
  }){
    return new TokenRecord({
      func,
      token
    });
  }
  enhancingObj.publish = function(topic, ...data){
    if (!topics.has(topic)){
      throw new Error(`No listener for ${topic} existing`);
    }
    var tokenRecords = topics.get(topic);
    tokenRecords.forEach( tokenRecord => {
      tokenRecord.func.apply(this, [...data]);
    })
  }
  
  enhancingObj.subscribe = function(topic, f){
    if (!topics.has(topic)){
      topics.set(topic, []);
    }
    let tokenId = uniqueId++;
    topics.get(topic).push(TokenRecord.of({
      token : tokenId,
      func : f
    }));
    return tokenId;
  }
  
  enhancingObj.unsubscribe = function(tokenId){
    var values = Array.from(topics.values());
    values.every( tokens => {
      let matchIndex = tokens.findIndex( token => {
        return token.token === tokenId;
      })
      
      if (matchIndex >= 0){
         tokens.splice(matchIndex, 1);   
        return false;
      }
      
      return true;
    })
  }
  
  
}(myObj))

 var tokenId1 = myObj.subscribe('hello', function(...data){
  Array.prototype.forEach.call(arguments, each => {
    console.log(`param is ${each}`)
  } )
  console.log('hello1')
});

 var tokenId2 = myObj.subscribe('hello', function(...data){
   Array.prototype.forEach.call(arguments, each => {
    console.log(`param is ${each}`)
  } )
  console.log('hello2')
});

myObj.publish('hello', 'ok', [1,2,3])
myObj.publish('hello1', 'ok')
// myObj.unsubscribe(tokenId1);
// myObj.unsubscribe(tokenId2);

Comments