面试过程中让你实现隔一秒执行红黄绿灯的循环
看到这个问题,你第一反应我猜你可能会选择直接用定时器实现,代码如下:
function red() {
console.log('red');
}
function green() {
console.log('green');
}
function yellow() {
console.log('yellow');
}
function index() {
setTimeout(function() {
red();
setTimeout(function() {
green();
setTimeout(function() {
yellow();
setTimeout(function() {
index();
},0);
},1000);
},1000);
},1000);
}
index();
如果你是一个初学者,你写出这段代码,你可能会觉得你很牛逼,很有成就感,因为功能确实实现了。但当你有点工作经验了你就会发现,卧槽,这代码那个傻逼写的,写的这么挫。确实,这代码耦合性高,改动如果逻辑复杂将会让人非常头疼,代码可读性也非常差,不利于调试,也没有一点函数封装的思想。如果你面试时使用这份答案,面试官肯定会让你优化代码,使用promise如何优化。使用promise你可以写出如下代码:
// 统一封装一个函数
function light(fun, timer) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(fun());
}, timer);
});
}
// 然后再调用
function index() {
light(red, 1000).then((data) => {
return light(green, 1000);
}).then((data) => {
return light(yellow, 1000);
}).then(() => {
index();
});
}
当你实现了这段代码以后,面试官会觉得你还不错,基本的promise还是会使用的,但他可能有会问你,你有了解过async和await吗,能用async 和await实现这个功能吗?如果你不了解generator函数的话你可能就不会了,async和await其实是它的语法糖,await 后面接的是一个promise返回对象,代码如下
function light(fun, timer) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(fun());
}, timer);
});
}
async function index() {
while(1) {
await light(red, 1000);
await light(green, 1000);
await light(yellow, 1000);
}
}
index();
是不是感觉这段代码比上面的可读性好多了,调试也方便,而且await后面的代码必须等他返回执行promise的resolve()才会继续往下执行,让你的代码看起来像同步执行的。
有兴趣的同学可以关注我一起交流学习,免费给你解答疑问哦。(前提是我能解决的前端问题)