最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 异步:信号灯控制器

    正文概述 掘金(李唐敏名)   2021-03-05   498

    题目

    分析

    可以从题目中拆分两个组件:

    1. 信号灯
    2. 控制器

    信号灯需要做的事情:

    1. 接收配置信息。
    2. 亮、闪烁。
    3. 结束后通知控制器。

    控制器需要做的事情:

    1. 接收配置信息,根据配置信息创建信号灯。
    2. 信号灯编排:接受信号灯的结束通知,并启动下一个信号灯。

    难点:

    1. 信号灯的亮、闪烁。
    2. 信号灯结束,控制器启动下一个信号灯。

    这里等待操作,显然需要通过异步来实现,我们可以先去复习Promise和async函数。

    控制台版

    function Light(color, duration, twinkleDuration) { // 信号灯
        let brightDuration = duration - twinkleDuration;
        function bright() {			// 亮
            return new Promise(function (resolve, reject) {
                console.log(`${color}灯开始亮`)
                setTimeout(resolve, brightDuration);
            })
        }
        function twinkle() {	// 闪烁
            return new Promise(function (resolve, reject) {
                console.log(`${color}灯开始闪烁`)
                setTimeout(resolve, twinkleDuration);
            })
        }
        function start() {	// 启动信号灯
            return new Promise(async function (resolve, reject) {
                await bright()				// ①
                await twinkle() 			// ②
                console.log(`${color}灯灭掉`)
                resolve()
            })
        }
        return {
            start
        }
    }
    function timer() { // 计时器,用来测试
        let start = new Date()
        let now = new Date()
        function next() {
            now = new Date()
            console.log(`第${Math.floor((now - start) / 1000)}秒`)
            setTimeout(next, 1000)
        }
        next()
    }
    async function LightControl(lightOptions) {	// 信号灯控制器
        for (let { color, duration, twinkleDuration } of lightOptions) {
            await Light(color, duration, twinkleDuration).start() 	// ③
        }
    }
    
    timer()
    LightControl([
        { color: "红", duration: 4000, twinkleDuration: 2000, },
        { color: "绿", duration: 5000, twinkleDuration: 3000, },
        { color: "黄", duration: 6000, twinkleDuration: 4000, },
    ])
    

    !!! 在①②③处,存在层次的回调,我们使用async函数来简化代码。

    输出结果:
    第0秒
    红灯开始亮
    第1秒
    红灯开始闪烁
    第2秒
    第3秒
    红灯灭掉
    绿灯开始亮
    第4秒
    第5秒
    绿灯开始闪烁
    第6秒
    第7秒
    第8秒
    绿灯灭掉
    黄灯开始亮
    第9秒
    第10秒
    黄灯开始闪烁
    第11秒
    第12秒
    第13秒
    第14秒
    黄灯灭掉
    第15秒
    第16秒
    

    输出符合预期,信号灯依次闪烁。

    Vue版

    下面,我们把代码稍微进行一下修改,让该信号灯显示在网页中。

    // @/components/LightControl.vue
    
    <template>
      <div>
        <Light v-for="(lightOption,index) of lightOptions"
               :lightOption="lightOption"
               :status="lightStatus[index]"
               :key="index"
        />
        <div>计时器:{{ time }}</div>
        <div>option: {{lightOptions}}</div>
      </div>
    </template>
    
    <script>
    import Light from '@/components/Light'
    
    export default {
      name: "LightControl",
      data: function () {
        return {
          lightOptions: [
            {color: "#FF0000", duration: 6000, twinkleDuration: 2000,},
            {color: "#00FF00", duration: 5000, twinkleDuration: 3000,},
            {color: "#FFFF00", duration: 6000},
          ],
          lightStatus: [0, 0, 0],
          time: 0,
        }
      },
      components: {
        Light
      },
      created() {
        this.lightControl(this.lightOptions)
        this.startTimer()
      },
      methods: {
        startTimer() {
          let start = new Date()
          let now = new Date()
          let that = this
          function next() {
            now = new Date()
            that.time = Math.floor((now - start) / 1000)
            setTimeout(next, 1000)
          }
          next()
        },
        changeStatus: function (i, value) {
          this.lightStatus.splice(i, 1, value)
        },
        createLight: function (color, duration, twinkleDuration=0, i) { // 信号灯
          let brightDuration = duration - twinkleDuration
          let that = this
    
          function bright() {			// 亮
            return new Promise(function (resolve) {
              that.changeStatus(i, 1)
              setTimeout(resolve, brightDuration);
            })
          }
    
          function twinkle() {	// 闪烁
            return new Promise(function (resolve) {
              that.changeStatus(i, 2)
              setTimeout(resolve, twinkleDuration);
            })
          }
    
          function start() {	// 启动信号灯
            return async function () {
              await bright()
              await twinkle()
              that.changeStatus(i, 0)
            }()
          }
    
          return {
            start
          }
        },
        lightControl: async function (lightOptions) {
          for (let i = 0; i < lightOptions.length; i++) {
            let {color, duration, twinkleDuration} = lightOptions[i]
            await this.createLight(color, duration, twinkleDuration, i).start()
          }
        }
      },
    }
    </script>
    
    <style scoped>
    
    </style>
    
    
    // @/components/Light.vue
    
    <template>
      <div :style="color" :class="lightClass">
    
      </div>
    </template>
    
    <script>
    export default {
      name: "Light",
      props: {
        lightOption: {
          type: Object,
          value: null,
        },
        status: {
          type: Number,
          value: 0,
        },
      },
      computed: {
        lightClass: function () { // 传入的 props => 类名 => 样式
          let subClass = 'close'
          console.log(this.status)
          if (this.status === 1) {
            subClass = 'on'
          } else if (this.status === 2) {
            subClass = 'fade'
          }
          return ['light', subClass]
        }
      },
      data: function () {
        return {
          color: "#FFFF00",
        }
      },
      created() {
        this.color = {
          background: this.lightOption.color
        }
      },
    }
    </script>
    
    <style scoped>
    .light {
      display: inline-block;
      height: 30px;
      width: 30px;
      border-radius: 30px;
    }
    
    .on {
      opacity: 1;
    }
    
    .close {
      opacity: 0.2;
    }
    
    @keyframes fade {
      from {
        opacity: 1.0;
      }
      50% {
        opacity: 0;
      }
      to {
        opacity: 1.0;
      }
    }
    
    .fade {
      animation: fade 618ms infinite;
    }
    
    </style>
    
    

    上述代码创建了两个Vue组件Light、LightControl,Light只是负责显示,控制逻辑都写在LightControl里。

    效果如下图:

    异步:信号灯控制器

    总结

    使用JavaScript提供的Promise和async函数,我们可以非常方便等待异步函数

    源码:https://gitee.com/litangmm/myblinker

    创作不易!如果对你有帮助,还请点赞收藏。 如果有疑惑可以在下方留言。 如果有什么建议,可以私信我。


    起源地下载网 » 异步:信号灯控制器

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元