18.JS红绿灯

循环打印红黄绿,这是一道非常经典的场景应用题。通过这个问题来对比几种异步编程方法:红灯 3s 亮一次,绿灯 1s 亮一次,黄灯 2s 亮一次;如何让三个灯不断交替重复亮灯?

三个亮灯函数:

function red() {
    console.log('red');
}
function green() {
    console.log('green');
}
function yellow() {
    console.log('yellow');
}

这道题复杂的地方在于需要“交替重复”亮灯,而不是“亮完一次”就结束了。

实现方式1(回调函数)

const task = (timer, light, callback) => {
  setTimeout(() => {
      if (light === 'red') {
          red()
      }
      else if (light === 'green') {
          green()
      }
      else if (light === 'yellow') {
          yellow()
      }
      callback()
  }, timer)
}
task(3000, 'red', () => {
  task(2000, 'green', () => {
      task(1000, 'yellow', Function.prototype)
  })
})

function red() {
  console.log('red');
}
function green() {
  console.log('green');
}
function yellow() {
  console.log('yellow');
}

// red
// green
// yellow

这里存在一个 bug:代码只是完成了一次流程,执行后红黄绿灯分别只亮一次。该如何让它交替重复进行呢?

实现方式2(递归)

上面提到过递归,可以递归亮灯的一个周期:

const task = (timer, light, callback) => {
  setTimeout(() => {
      if (light === 'red') {
          red()
      }
      else if (light === 'green') {
          green()
      }
      else if (light === 'yellow') {
          yellow()
      }
      callback()
  }, timer)
}

const step = () => {
  task(3000, 'red', () => {
      task(2000, 'green', () => {
          task(1000, 'yellow', step)
      })
  })
}
step()

function red() {
  console.log('red');
}
function green() {
  console.log('green');
}
function yellow() {
  console.log('yellow');
}

// red
// green
// yellow
// red
// green
// yellow
// red
// green

实现方式3(Promise)


const task = (timer, light) => 
    new Promise((resolve, reject) => {
        setTimeout(() => {
            if (light === 'red') {
                red()
            }
            else if (light === 'green') {
                green()
            }
            else if (light === 'yellow') {
                yellow()
            }
            resolve()
        }, timer)
    })
const step = () => {
    task(3000, 'red')
        .then(() => task(2000, 'green'))
        .then(() => task(2100, 'yellow'))
        .then(step)
}
step()


function red() {
  console.log('red');
}
function green() {
  console.log('green');
}
function yellow() {
  console.log('yellow');
}

// red
// green
// yellow
// red
// green
// yellow
// red
// green

实现方式4(async和await)


const task = (timer, light) =>
  new Promise((resolve, reject) => {
    setTimeout(() => {
      if (light === 'red') {
        red()
      }
      else if (light === 'green') {
        green()
      }
      else if (light === 'yellow') {
        yellow()
      }
      resolve()
    }, timer)
  })
const taskRunner = async () => {
  await task(3000, 'red')
  await task(2000, 'green')
  await task(2100, 'yellow')
  taskRunner()
}
taskRunner()


function red() {
  console.log('red');
}
function green() {
  console.log('green');
}
function yellow() {
  console.log('yellow');
}

// red
// green
// yellow
// red
// green
// yellow
// red
// green

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值