交通灯
Sunny-117 opened this issue · 19 comments
解法一:回调方式实现
@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()
解法二: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()
解法三: 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()
timer为什么不统一设置1000
解法三: 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')
}
}
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: @.***>
卡不死的,因为循环里面用了异步,你直接在浏览器里面跑一下就知道了。
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()
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()
//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()
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)
}
// 循环打印红灯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();
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();
基于 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();
方案二:基于 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);
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();
很多题,我都不知道题是什么,就光有一个标题,全靠自己查吗 😭
红灯3秒亮一次,黄灯2秒亮一次,绿灯1秒亮一次;如何让三个灯不断交替重复亮灯?
// promise 红绿灯
const task = (time, type) => {
return new Promise(res => {
setTimeout(() => {
if (type === 'green') {
console.log('绿灯')
}
else if (type === 'yellow') {
console.log('黄灯')
}
else if (type === 'red') {
console.log('红灯')
}
res()
}, time);
})
}
async function run(time, start = true) {
if (start) {
console.log('开始 绿灯')
start = false
}else{
await task(time, 'green')
}
task(time, 'yellow').then(() => task(time, 'red')).then(() => run(time, start))
}
run(300)