|
@@ -0,0 +1,49 @@
|
|
|
+<header>PedestrianTrafficLight</header>
|
|
|
+
|
|
|
+<body>
|
|
|
+ <div id="red" style="background-color: red">Red</div><br>
|
|
|
+ <div id="green" style="background-color: black;">Green</div><br>
|
|
|
+ <button id="btn">GO</button>
|
|
|
+
|
|
|
+ <script>
|
|
|
+ const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms))
|
|
|
+ async function trafficLight(red, green, goBtn, cycDelay, pressPeriod) {
|
|
|
+ let isRed = true;
|
|
|
+ let lastBtnPress = undefined;
|
|
|
+ let btnPress = domEventPromise(goBtn, 'click');
|
|
|
+ function domEventPromise(element, eventName) {
|
|
|
+ function executor(resolve) {
|
|
|
+ function myOnClick(event) {
|
|
|
+ element.removeEventListener(eventName, myOnClick);
|
|
|
+ btnPress = domEventPromise(goBtn, 'click');
|
|
|
+ resolve({ isRed: false, isButton: true });
|
|
|
+ }
|
|
|
+ element.addEventListener(eventName, myOnClick);
|
|
|
+ }
|
|
|
+ return new Promise(executor);
|
|
|
+ }
|
|
|
+ while (true) {
|
|
|
+ let cycle = new Promise(
|
|
|
+ async resolve => {
|
|
|
+ await delay(cycDelay);
|
|
|
+ resolve({ isRed: !isRed, isButton: false });
|
|
|
+ });
|
|
|
+ let res = await Promise.race([cycle, btnPress]);
|
|
|
+ if (res.isButton) {
|
|
|
+ let isSkipButton = !isRed || (lastBtnPress && (new Date() - lastBtnPress) < pressPeriod);
|
|
|
+ if (isSkipButton)
|
|
|
+ res = await cycle;
|
|
|
+ lastBtnPress = new Date();
|
|
|
+ }
|
|
|
+ isRed = res.isRed;
|
|
|
+ isRed ? enableLight(red, "red", green) : enableLight(green, "green", red);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const enableLight = (fireElement, color, disFlashElement) => {
|
|
|
+ fireElement.style.backgroundColor = color;
|
|
|
+ disFlashElement.style.backgroundColor = "black";
|
|
|
+ }
|
|
|
+ let cycDelay = 5000;
|
|
|
+ trafficLight(red, green, btn, cycDelay, cycDelay / 2 * 3);
|
|
|
+ </script>
|
|
|
+</body>
|