[Javascript] Broadcaster + Operator + Listener pattern -- 10. Define a Function to Set Common Behaviors in Operators

In our previous code, we have seen this partten for operators:

复制代码
// #region operators
const concat = curry((broadcaster, listener) => {
  let string = '';
  return broadcaster((value) => {
    if (value === done) {
      listener(done);
      return;
    }
    listener((string += value));
  });
});
 
const map = curry((transform, broadcaster, listener) => {
  return broadcaster((value) => {
    if (value === done) {
      listener(done);
      return;
    }
    listener(transform(value));
  });
});
 
const filter = curry((predicator, broadcaster, listener) => {
  return broadcaster((value) => {
    if (value === done) {
      listener(done);
      return;
    }
    if (predicator(value)) {
      listener(value);
    }
  });
});
// #endregion
复制代码

 

We can create a function to reduce the code:

const createOperator = curry((operator, broadcaster, listener) => {

})

 

let's say, the new function is called 'createOperator', it takes an operator, a broadcaster, and a istener.

The way we want to use it as:

const concat = createOperator((broadcaster, listener) => {
  let string = '';
  return broadcaster((value) => {
    listener((string += value));
  });
});

As you can notify, we remove the if condition.

 

Step1: Strict refoacting:

const createOperator = curry((operator, broadcaster, listener) => {
  return operator(broadcaster, listener)
})

Now, it works almost the same as before, just without if condition check.

 

Step2: This time we want to create a new "broadcaster" and invoke the original broadcaster inside new broadcaster.

1. skeleton

const createOperator = curry((operator, broadcaster, listener) => {
  // new a new broadcaster and invoke original broadcaster inside new broadcaster
  return operator((behaviorListener) => {
    
  }, listener)
})

So what is "behaviorListener": it actual refer to:

const concat = createOperator((broadcaster, listener) => {
  let string = '';
  return broadcaster((value) => {
    listener((string += value));
  });
});

2. invoke the original "broadcaster":

const _createOperator = curry((operator, broadcaster, listener) => {
  // new a new broadcaster and invoke original broadcaster inside new broadcaster
  return operator((behaviorListener) => {
    return broadcaster((value) => {
      behaviorListener(value)
    })
  }, listener)
})

We want to pass the value to "behaviorListener" which refer to the highlighted code.

 

Step3: Add common code:

复制代码
const _createOperator = curry((operator, broadcaster, listener) => {
  // new a new broadcaster and invoke original broadcaster inside new broadcaster
  return operator((behaviorListener) => {
    // override the default broadcaster
    return broadcaster((value) => {
      // apply common logic
      if (value === done) {
        // stop outer listen to continue emitting values
        listener(done)
        return
      }
      behaviorListener(value)
    })
  }, listener)
})
复制代码

We call "listener(done)" in order to stop the source futhur emtting the values.

---

Put all together:

复制代码
const createOperator = curry((operator, broadcaster, listener) => {
  // new a new broadcaster and invoke original broadcaster inside new broadcaster
  return operator((behaviorListener) => {
    // override the default broadcaster
      return broadcaster(value => {
        // apply common logic
        if(value === done) {
          // stop outer listen to continue emitting values
          listener(done)
          return
        }
        // otherwise, we want to pass forward the value to listener
        behaviorListener(value)
      })
  }, listener)
})
复制代码

 

Step4: Refactoring operators:

复制代码
const concat = createOperator((broadcaster, listener) => {
  let string = '';
  return broadcaster((value) => {
    listener((string += value));
  });
});

const map = transform => createOperator((broadcaster, listener) => {
  return broadcaster((value) => {
    listener(transform(value));
  });
});

const filter = predicator => createOperator((broadcaster, listener) => {
  return broadcaster((value) => {
    if (predicator(value)) {
      listener(value);
    }
  });
});
复制代码

 

-- working code example --

  

posted @   Zhentiw  阅读(151)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2019-10-25 [Schematics] 1. Copy and Manipulate Template
2019-10-25 [Schematics] 0. Schematics "Hello World"
2019-10-25 [RxJS] Subject asObservable() method
2019-10-25 [Flutter] Passing the data backwards thought Navigator
2018-10-25 [Unit Testing] Fundamentals of Testing in Javascript
2016-10-25 [Debug] Chrome Devtools: Elements - Console Integration
2016-10-25 [Flexbox] Use Flex to Scale Background Image
点击右上角即可分享
微信分享提示