红绿灯效果

本实现来自 winter《重学前端》第16节 JavaScript执行(一): Promise里的代码为什么比setTimeout先执行?
中的最后的问题,使用实现一个红绿灯效果。

<body>
    <style>
        .redgreenlight{
            width: 100px;
            height: 100px;
            margin: 0 auto;
            border-radius: 50%;
            line-height: 100px; 
            text-align: center;
            background-color: #eee;
            border: double 3px gray;
        }
        .btn{
            display: inline-block;
            background-color: #ddd;
            transition: transform 200ms linear;
            border-radius: 5px;
        }
        .btn:hover{
            background-color: #888;
        }
        .btn:active{
            transform: scale(.9);
        }
    </style>
    打开电源,红绿灯开始工作
    <div class="btn" id="btn" onclick="lightopen()">启动</div>
    <div class="redgreenlight" id="light">红绿灯</div>
    <script>

        // 延时的promise包装
        function wait(delay){
            return new Promise((resolve, reject) => {
                setTimeout(resolve, delay)
            })
        }

        // 同步函数promise包装
        function asyncDeal(asyncfn){
            return new Promise((resolve, reject) => {
                asyncfn()
                resolve()
            })
        }
        
        // 业务目标

        // 绿色 3
        // 黄色 1
        // 红色 2



        // 启动队列循环
        function lightopen(){
            btn.onclick = null
            // promise队列执行
            return Promise.resolve()
                .then(() => asyncDeal(() => {
                    light.style.backgroundColor = "#00ff00"
                    light.innerText = ('绿灯三秒')
                }))
                .then(() => wait(3000))
                .then(() => asyncDeal(() => {
                    light.style.backgroundColor = "#ff8800"
                    light.innerText = ('黄灯一秒')
                }))
                .then(() => wait(1000))
                .then(() => asyncDeal(() => {
                    light.style.backgroundColor = "#ff0000"
                    light.innerText = ('红灯俩秒')
                }))
                .then(() => wait(2000))
                .then(() => lightopen())
        }

        
    </script>
    
</body>

红绿灯效果