Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

交通灯 #164

Open
Sunny-117 opened this issue Nov 3, 2022 · 18 comments
Open

交通灯 #164

Sunny-117 opened this issue Nov 3, 2022 · 18 comments

Comments

@Sunny-117
Copy link
Owner

No description provided.

@LevyEvans-s
Copy link
Contributor

LevyEvans-s commented Nov 4, 2022

解法一:回调方式实现

@author: 北方银时
@blog: https://juejin.cn/user/602954369606199

// 模拟红灯亮
function red() {
  console.log('red')
}

//模拟绿灯亮
function green() {
  console.log('green')
}

//模拟黄灯亮
function yellow() {
  console.log('yellow')
}

const task = (timer, light, callback) => {
  setTimeout(() => {
    if (light === 'red') {
      red()
    } else if (light === 'green') {
      green()
    } else if (light === 'yellow') {
      yellow()
    }
    //灯亮完之后执行回调
    callback()
  }, timer)
}

//存在bug: 代码只完成了一次交替亮灯
// task(3000, 'red', () => {
//   task(1000, 'green', () => {
//     task(2000, 'yellow', Function.prototype)
//   })
// })

//解决方案:通过递归让亮灯的一个周期无限循环
const step = () => {
  task(3000, 'red', () => {
    task(1000, 'green', () => {
      task(2000, 'yellow', step)
    })
  })
}

step()

@LevyEvans-s
Copy link
Contributor

解法二:Promise方案

@author: 北方银时
@blog: https://juejin.cn/user/602954369606199

// 模拟红灯亮
function red() {
  console.log('red')
}

//模拟绿灯亮
function green() {
  console.log('green')
}

//模拟黄灯亮
function yellow() {
  console.log('yellow')
}

const task = (timer, light) => {
  return 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(1000, 'green'))
    .then(() => task(2000, 'yellow'))
    .then(step)
}

step()

@LevyEvans-s
Copy link
Contributor

解法三: Async/await 大杀器

@author: 北方银时
@blog: https://juejin.cn/user/602954369606199

function red() {
  console.log('red')
}

function green() {
  console.log('green')
}

function yellow() {
  console.log('yellow')
}

const task = (timer, light) => {
  return 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(1000, 'green')
  await task(2000, 'yellow')
  taskRunner()
}

taskRunner()

@Tsuizen
Copy link

Tsuizen commented Feb 7, 2023

timer为什么不统一设置1000

@SecurityILiu
Copy link

SecurityILiu commented Feb 7, 2023 via email

@akira-cn
Copy link

akira-cn commented Feb 9, 2023

解法三: Async/await 大杀器

@author: 北方银时 @blog: https://juejin.cn/user/602954369606199

function red() {
  console.log('red')
}

function green() {
  console.log('green')
}

function yellow() {
  console.log('yellow')
}

const task = (timer, light) => {
  return 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(1000, 'green')
  await task(2000, 'yellow')
  taskRunner()
}

taskRunner()

既然用了异步语法,不需要再用递归,直接用循环更优雅:

const taskRunner = async () => {
    while(1) {
        await task(3000, 'red')
        await task(1000, 'green')
        await task(2000, 'yellow')
    }
}

@SecurityILiu
Copy link

SecurityILiu commented Feb 9, 2023 via email

@akira-cn
Copy link

js是单线程,这样会卡死的

------------------ 原始邮件 ------------------ 发件人: @.>; 发送时间: 2023年2月9日(星期四) 上午10:59 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [Sunny-117/js-challenges] 交通灯 (Issue #164) 解法三: Async/await 大杀器 @author: 北方银时 @blog: https://juejin.cn/user/602954369606199 function red() { console.log('red') } function green() { console.log('green') } function yellow() { console.log('yellow') } const task = (timer, light) => { return 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(1000, 'green') await task(2000, 'yellow') taskRunner() } taskRunner() 既然用了异步语法,不需要再用递归,直接用循环更优雅: const taskRunner = async () => { while(1) { await task(3000, 'red') await task(1000, 'green') await task(2000, 'yellow') } } — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

卡不死的,因为循环里面用了异步,你直接在浏览器里面跑一下就知道了。

@Digoler
Copy link

Digoler commented Mar 11, 2023

function red() {
    console.log('red')
}

function green() {
    console.log('green')
}

function yellow() {
    console.log('yellow')
}
// 要求:红灯3秒亮一次,黄灯2秒亮一次,绿灯1秒亮一次。
const light = function(timer, cb) {
    return new Promise(resolve => {
        setTimeout(() => {
            cb()
            resolve()
        }, timer);
    })
}

const step = function() {
    Promise.resolve().then(() => {
        return light(3000, red)
    }).then(() => {
        return light(2000, green)
    }).then(() => {
        return light(1000, yellow)
    }).then(() => {
        return step()
    })
}

step()

@xun-zi
Copy link

xun-zi commented Mar 14, 2023

function red() {
        console.log('red')
    }
    function green() {
        console.log('green')
    }
    function blue() {
        console.log('blue')
    }

    function sleep(timer) {
        return new Promise((resovle, reject) => {
            setTimeout(resovle, 3000);
        })
    }

    async function task() {
        while (1) {
            await sleep(1000);
            red();
            await sleep(2000);
            blue();
            await sleep(3000);
            green();
        }
    }
    task()

@Banks1y
Copy link

Banks1y commented Jul 6, 2023

//promise then
function Traficlight(light,timer){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log(light);
            resolve()
        },timer)
    })
}
const step = ()=>{
    Traficlight('red',3000).then(()=>Traficlight('yellow',2000)).then(()=>Traficlight('green',1000)).then(step)
}
step()
//async await
function Traficlight(light,timer){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log(light);
            resolve()
        },timer)
    })
}
const step = async()=>{
    await Traficlight('red',3000)
    await Traficlight('yellow',2000)
    await Traficlight('green',1000)
    step()
}
step()

@kezoo
Copy link

kezoo commented Aug 16, 2023

function simTrafficSignal () {
  const  list = [
    {name: 'r', offset: 3, bg: 'pink'},
    {name: 'g', offset: 2, bg: 'cyan'},
    {name: 'y', offset: 1, bg: 'orange'},
  ]
  const cls = `tfSn`
  let el = document.querySelector('.'+cls)
  if (!el) {
    el = document.createElement('div')
    el.className = cls
    el.style.width = `1rem`
    el.style.height = `1rem`
    document.body.appendChild(el)
  }
  const fn = (idx) => {
    const l = list[idx] || list[0]
    if (!list[idx]) { idx = 0 }
    el.style.backgroundColor = l.bg;
    setTimeout(() => fn(++idx), l.offset*1000)
  }
  fn(0)
}

@HuangDaohong
Copy link

// 循环打印红灯3秒,绿灯1秒,黄灯2秒,不断交替重复亮灯
function light (name, timer) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(name);
      resolve();
    }, timer);
  });
}

const lightList = [
  { name: 'red', timer: 3000 },
  { name: 'green', timer: 1000 },
  { name: 'yellow', timer: 2000 }
];

async function runLights () {
  // await light('red', 3000);
  // await light('green', 1000);
  // await light('yellow', 2000);
  for (let i = 0; i < lightList.length; i++) {
    const { name, timer } = lightList[i];
    await light(name, timer);
  }
  runLights();
}
runLights();

@zhongqiaoshan
Copy link

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

  const list = {
    green: green,
    yellow: yellow,
    red: red,
  };

  const stak = (fun, time) => {
    return new Promise((resolve, rejected) => {
      setTimeout(() => {
        list[fun]();
        resolve();
      }, time);
    });
  };

  const step = async () => {
    await stak("red", 3000);
    await stak("yellow", 3000);
    await stak("green", 3000);
  };
  step();

@wangjs-jacky
Copy link

基于 tapable 思想:红绿灯问题可转化为异步串行 + 循环结构构造

/* 方案一:封装 Promise 列表 */
const light = (callback, seconds = 500) => {
  return () => {
    return new Promise(resolve => {
      setTimeout(() => {
        callback();
        resolve();
      }, seconds);
    })
  }
}

const tasks = [light(red), light(yellow), light(green)];

/* 异步串行写法
   a().then(()=>b()).then(()=>c())
      .then(()=>console.log("串执行结束"))
      .catch(()=> console.log("串行执行报错"))
*/
const taskRun = () => {
  const [first, ...otherTasks] = tasks;
  return new Promise((resolve, reject) => {
    otherTasks.reduce((pre, cur) => {
      return pre.then(() => cur())
    }, first())
      .then(() => {
        /* taskRun(); */
        resolve();
      })
  })
}

/* 包裹 taskRun 为递归 */
const loopTask = async () => {
  await taskRun().then(() => console.log("结束"))
  loopTask();
}

/* 启动循环 */
loopTask();

@wangjs-jacky
Copy link

方案二:基于 koa 函数的 compose 思想

/* 构造延时 */
const light = (cb, delay = 1000) => {
  return (next) => setTimeout(() => {
    cb();
    /* 当前函数执行后,触发 next 函数 */
    next();
  }, delay)
}

const tasks = [light(red), light(yellow), light(green)];

const compose = (tasks) => {
  const dispatch = (i) => {
    /* 移动指针至头部 */
    if (i === tasks.length) {
      i = 0;
    }
    /* 取出下一个任务 */
    const next = () => dispatch(i + 1)
    /* 取出当前任务 */
    const curTask = tasks[i];
    return curTask(next);
  }
  dispatch(0);
}
compose(tasks);

@yuan0221
Copy link

function sleep(time) {
  return new Promise(resolve => {
    setTimeout(resolve, time);
  })
}

async function go() {
  green();
  await sleep(1000);
  yellow();
  await sleep(300);
  red();
  await sleep(500);
  go();
}

go();

@shenxiang11
Copy link

很多题,我都不知道题是什么,就光有一个标题,全靠自己查吗 😭

红灯3秒亮一次,黄灯2秒亮一次,绿灯1秒亮一次;如何让三个灯不断交替重复亮灯?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests