zl程序教程

您现在的位置是:首页 >  其他

当前栏目

一道关于Promise应用的面试题

面试题应用 关于 Promise 一道
2023-09-14 08:59:36 时间

题目:红灯三秒亮一次,绿灯一秒亮一次,黄灯2秒亮一次;如何让三个灯不断交替重复亮灯?(用Promse实现)

三个亮灯函数已经存在:

function red(){

 console.log(red);

function green(){

 console.log(green);

function yellow(){

 console.log(yellow);

}

这道题首先考察Promise的应用,Promise的详细说明请看我的这篇文章:闲话Promise机制。首先我们需要一个函数来实现时间控制:

var tic = function(timmer, cb){

 return new Promise(function(resolve, reject) {

 setTimeout(function() {

 cb();

 resolve();

 }, timmer);

};

如果把问题简化一下,如果只需要一个周期,那么利用Promise应该这样写:

var d = new Promise(function(resolve, reject){resolve();});

var step = function(def) {

 def.then(function(){

 return tic(3000, red);

 }).then(function(){

 return tic(2000, green);

 }).then(function(){

 return tic(1000, yellow);

}

现在一个周期已经有了,剩下的问题是如何让他无限循环。说道循环很容易想到for while do-while这三个,比如:

var d = new Promise(function(resolve, reject){resolve();});

var step = function(def) {

 while(true) {

 def.then(function(){

 return tic(3000, red);

 }).then(function(){

 return tic(2000, green);

 }).then(function(){

 return tic(1000, yellow);

}

如果你是这样想的,那么恭喜你成功踩了坑!这道题的第二个考查点就是setTimeout相关的异步队列会挂起知道主进程空闲。如果使用while无限循环,主进程永远不会空闲,setTimeout的函数永远不会执行!

正确的解决方法就是这道题的第三个考查点——递归!!!解决方案如下:

var d = new Promise(function(resolve, reject){resolve();});

var step = function(def) {

 def.then(function(){

 return tic(3000, red);

 }).then(function(){

 return tic(2000, green);

 }).then(function(){

 return tic(1000, yellow);

 }).then(function(){

 step(def);

}

整体代码如下:

function red(){

 console.log(red);

function green(){

 console.log(green);

function yellow(){

 console.log(yellow);

var tic = function(timmer, cb){

 return new Promise(function(resolve, reject) {

 setTimeout(function() {

 cb();

 resolve();

 }, timmer);

var d = new Promise(function(resolve, reject){resolve();});

var step = function(def) {

 def.then(function(){

 return tic(3000, red);

 }).then(function(){

 return tic(2000, green);

 }).then(function(){

 return tic(1000, yellow);

 }).then(function(){

 step(def);

step(d);

同时可以看到虽然Promise可以用来解决回调地狱问题,但是仍然不可避免的会有回调出现,更好的解决方案是利用Generator来减少回调:

var tic = function(timmer, str){

 return new Promise(function(resolve, reject) {

 setTimeout(function() {

 console.log(str);

 resolve(1);

 }, timmer);


如何手写一个Promise 手写实现Promise是一道经典的前端面试题。比如在美团,Promise几乎就是必考题,在其它互联网一线大厂也是高频题目。 Promise的实现相对比较复杂,考虑的逻辑也比较多,下面带着大家逐一分析,找到其关键点、以及如何手写一个Promise。