Promise面试题目(红黄蓝灯交替亮)

1,714 阅读2分钟

题目:第1秒红灯亮,第2秒黄灯亮,第3秒蓝灯亮;如何让三个灯不断交替重复亮灯?(用Promise实现)

不使用Promise

按照逻辑依次执行:首先是红灯亮,调用黄灯亮;黄灯亮,调用蓝灯亮;蓝灯亮,再调用红灯亮...可以看到循环回调的现象。

  function lightRed() {
    setTimeout(()=>{
      console.log("red");
      lightYellow();
    }, 1000);
  }

  function lightYellow() {
    setTimeout(()=>{
      console.log("yellow");
      lightBlue();
    }, 1000)
  }

  function lightBlue() {
    setTimeout(()=>{
      console.log("blue");
      lightRed();
    }, 1000)
  }

  lightRed();

使用Promise

对上面代码进行封装

  function light(color, delay) {
    return new Promise(resolve => {
      setTimeout(()=>{
        console.log(color);
        resolve();
      }, delay)
    })
  }
  //很容易想到下面的代码
   light("red", 1000).then(()=>{
    light("yellow", 1000).then(()=>{
      light("blue", 1000).then(()=>{

      })
    })
  })
  //或者链式调用
  light("red", 1000).then(()=>{
    return light("yellow", 1000);
  }).then(()=>{
    return light("blue", 1000);
  })

这样我们只能执行一次;怎么可以循环多次呢?那就是封装成一个函数,在这个函数中调用自己。

  const promiseLoop = ()=>{
    light("red", 1000).then(()=>{
      return light("yellow", 1000);
    }).then(()=>{
      return light("blue", 1000);
    }).then(()=>{
      promiseLoop();
    })
  }
  promiseLoop();

async await升级版

    const loop = async ()=>{
    	await light("red", 1000);
    	await light("yellow", 1000);
    	await light("blue", 1000);
    	loop();
    }
    loop();

通过对比,我们不难发现 async await 比 Promise 更容易理解。这里多补充一些:

async 函数返回一个 Promise 对象;
async 函数内部 return 语句返回的值,会成为 then 方法回调函数的参数。

    async function f() {
        return "hello async"
    }
    f().then(res=>{
    	console.log(res)
    })

对比 Promise 的写法:

    function f() {
        return new Promise(resolve => {
        	resolve("hello promise");
        })
    }
    f().then(res=>{
	    console.log(res)
    })

可以看到没有await的async和Promise实现同样的效果。

await只能用在async函数内部,不能单独使用。
await相当于 new Promise(resolve=>{}).then()

类比使用例子:

    let result = f(10).then(res=>{
    	console.log("promsie2: "+ res);
    	return 2 * res;
    }).then(res=>{
	    console.log("promise3: "+res);
    	return 3 * res;
    });
    
    result.then(res=>{
    	console.log(res);
    });

    async function test() {
        let res1 = await f(10);
        console.log(res1)
        let res2 = await f(res1*2);
        console.log(res2);
    }
    test();

可以看出,由于await的存在使得 promise的then方法使用更加灵活。没有await我们只能在前一个then方法中调用另外一个方法;await的存在可以获取 then 里面的返回值,作为下一步灵活使用。