const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms)) async function trafficLight(dom) { dom = document.getElementById('light1') let green = document.getElementById('green') let red = document.getElementById('red') let yellow = document.getElementById('yellow') while (true) { red.style.visibility = 'visible' green.style.visibility = 'hidden' yellow.style.visibility = 'hidden' await delay(3000) yellow.style.visibility = 'visible' green.style.visibility = 'hidden' red.style.visibility = 'hidden' await delay(1000) green.style.visibility = 'visible' red.style.visibility = 'hidden' yellow.style.visibility = 'hidden' await delay(3000) yellow.style.visibility = 'visible' green.style.visibility = 'hidden' red.style.visibility = 'hidden' await delay(1000) } } trafficLight(); //trafficLight2 function domEventPromise(element, eventName) { return new Promise((resolve, reject) => { element.addEventListener(eventName, (e) => { resolve(e) trafficLight2(e) }) element.removeEventListener(eventName, (e) => { resolve(e) trafficLight2(e) }) }) } async function trafficLight2() { while (true) { if (true) { red1.style.visibility = "hidden"; green1.style.visibility = "visible"; btn.disabled = true; await delay(4000); btn.disabled = false; await Promise.race([ delay(1000), domEventPromise(btn, "click").then((e) => console.log("event click happens", e) ), ]); } if (true) { btn.disabled = true; green1.style.visibility = "hidden"; red1.style.visibility = "visible"; await delay(5000); } } } trafficLight2()