<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [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 --

      import { curry, compose, toUpper, pipe } from 'ramda';
      
      // #region listeners
      const _log = (value) => console.log(value);
      // #endregion
      
      // #region broadcasters
      const done = Symbol('done');
      const addListener = curry((element, eventType, listener) => {
        return element.addEventListener(evenType, listener);
      });
      const createInterval = curry((time, listener) => {
        let i = 0;
        const id = setInterval(() => {
          listener(i++);
        }, time);
        return () => {
          clearInterval(id);
        };
      });
      const createForOf = curry((iterator, listener) => {
        const id = setTimeout(() => {
          for (let item of iterator) {
            listener(item);
          }
          listener(done);
        }, 0);
        return () => {
          clearTimeout(id);
        };
      });
      const createZipOf = curry((broadcaster1, broadcaster2, listener) => {
        let cancelBoth;
        let buffer1 = [];
        const cancel1 = broadcaster1((value) => {
          buffer1.push(value);
          if (buffer2.length) {
            listener([buffer1.shift(), buffer2.shift()]);
            if (buffer1[0] === done || buffer2[0] === done) {
              listener(done);
              cancelBoth();
            }
          }
        });
      
        let buffer2 = [];
        const cancel2 = broadcaster2((value) => {
          buffer2.push(value);
          if (buffer1.length) {
            listener([buffer1.shift(), buffer2.shift()]);
            if (buffer1[0] === done || buffer2[0] === done) {
              listener(done);
              cancelBoth();
            }
          }
        });
        cancelBoth = () => {
          cancel1();
          cancel2();
        };
        return cancelBoth;
      });
      // #endregion
      
      // #region operators
      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)
      })
      
      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);
          }
        });
      });
      // #endregion
      const transform =  pipe(
          map((x) => x[1]),
          filter((x) => x !== ','),
          concat,
          map(toUpper)
        );
      let typeGreeting = transform(
        createZipOf(createInterval(100), createForOf('My Zipo'))
      );
      const cancelGreating = typeGreeting(_log)
      // cancelGreating()
      
      const myZip = (broadcaster1, broadcaster2) => (...operators) => {
        return pipe(...operators)(createZipOf(broadcaster2, broadcaster2))
      }
      

        

      posted @ 2020-10-25 21:54  Zhentiw  閱讀(162)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 欧美老熟妇乱子伦牲交视频| 蜜臀av一区二区三区精品| 在线观看无码av五月花| 色婷婷亚洲精品综合影院| 国产成人一区二区三区免费| 高h纯肉无码视频在线观看| 西宁市| 久久成人伊人欧洲精品| 亚洲AVAV天堂AV在线网阿V| 东至县| 国产一级特黄性生活大片| 亚洲午夜香蕉久久精品| 中文字幕久区久久中文字幕| 日本成熟少妇激情视频免费看| 国产精品剧情亚洲二区| 人妻少妇88久久中文字幕| 永久免费无码av在线网站| 国产精品免费AⅤ片在线观看| 综合色综合色综合色综合| 77777五月色婷婷丁香视频| 亚洲一二三四区中文字幕| 成人午夜在线观看日韩| 成人无码视频在线观看免费播放 | 四房播色综合久久婷婷| 中文www天堂| 精品亚洲国产成人性色av| 精品人妻中文字幕在线| 丰顺县| 国产成人精品一区二区三区免费| 中文人妻AV高清一区二区| 熟女人妻精品一区二区视频| 平塘县| 精品亚洲国产成人av| 无码精品一区二区免费AV| 日韩中文免费一区二区| 青青青青久久精品国产| 国产色视频网站免费| 少妇撒尿一区二区在线视频| 欧美日韩精品一区二区三区高清视频| 在线高清免费不卡全码| 亚洲av激情一区二区三区|