[Javascript] Broadcaster + Operator + Listener pattern -- 18. Create a Win Condition with a mapDone Operator

Many streams of events end when a certain condition is met. When we run into that condition, we'll want to pass down our own custom values. This lessons walks through adding a done condition to hangman and how we can use new operators to control what happens when it's done.

 

Continue with previous post.

 

1. Set a win logic:

let hangman = pipe(map(hangmanLogic), applyOperator(word), stringConcat);
hangman(inputValue)(log);

// to

let hangman = pipe(map(hangmanLogic), applyOperator(word), stringConcat);
let play = hangman(inputValue);
let winPipe = pipe(filter((str) => !str.includes("*")));
let win = winPipe(play);

play(console.log);
win(() => {
  console.log("you win");
});

When we enter 'honeycomb' in the input, it will log out 'you win', but as you continue typing, 'you win' continue pop up:

/*
honeycomb 
you win 
honeycombb
you win 
honeycombbbb 
you win 
*/

 

 

2. doneCondition operator:

let hangman = pipe(map(hangmanLogic), applyOperator(word), stringConcat);

let doneCondition = (condition) => (broadcaster) => (listener) => {
  let cancel = filter(condition)(broadcaster)((value) => {
    listener(done);
    cancel();
  });

  return () => {
    cancel();
  };
};

let winPipe = pipe(doneCondition((str) => !str.includes("*")));
let play = hangman(inputValue);
let win = winPipe(play);

play(console.log);
win(() => {
  console.log("you win");
});

Now, 'you win' only log out once.

 

3. Pass 'you win' from a operator:

let hangman = pipe(map(hangmanLogic), applyOperator(word), stringConcat);

let doneCondition = (condition) => (broadcaster) => (listener) => {
  let cancel = filter(condition)(broadcaster)((value) => {
    listener(done);
    cancel();
  });

  return () => {
    cancel();
  };
};

let mapDone = (doneValue) => (broadcaster) => (listener) => {
  broadcaster((value) => {
    if (value === done) {
      listener(doneValue);
    }
  });
};

let winPipe = pipe(
  doneCondition((str) => !str.includes("*")),
  mapDone("you win!")
);
let play = hangman(inputValue);
let win = winPipe(play);

play(console.log);
win(console.log);

 

4. Cancel 'play' when 'win':

let hangman = pipe(map(hangmanLogic), applyOperator(word), stringConcat);

let doneCondition = (condition) => (broadcaster) => (listener) => {
  let cancel = filter(condition)(broadcaster)((value) => {
    listener(done);
    cancel();
  });

  return () => {
    cancel();
  };
};

let mapDone = (doneValue) => (broadcaster) => (listener) => {
  broadcaster((value) => {
    if (value === done) {
      listener(doneValue);
    }
  });
};
let cancelWhen = (cancelBroadcaster) => (broadcaster) => (listener) => {
  let cancel = broadcaster(listener);

  let cancel2 = cancelBroadcaster(() => {
    cancel();
  });

  return () => {
    cancel();
    cancel2();
  };
};

let winPipe = pipe(
  doneCondition((str) => !str.includes("*")),
  mapDone("you win!")
);
let play = hangman(inputValue);
let win = winPipe(play);

let rules = pipe(cancelWhen(win));
let playWithWin = rules(play);
playWithWin(console.log);
win(console.log);

 

posted @ 2020-11-17 02:40  Zhentiw  阅读(141)  评论(0编辑  收藏  举报