用一道题目来验证你的JS功底,真香~

7,191 阅读2分钟

鼠年的春节只有三个字'宅~宅~宅~',宅来无事想起之前碰到的一个JS题目,感觉还是蛮有趣的,放出来大家一起思考下~

首先我们说一下题目(需求来了,面对疾风吧~)

/**
 * 请写出两种或两种以上实现方法满足: execute 对应的id按顺序打印
 * PS: 尝试只修改start函数体
 *
 * 输出结果参考:
 * id 0
 * id 1
 * id 2
 * id 3
 * id 4
 */

function start(id) {
  execute(id).catch(console.error);
}

// 测试代码 (请勿更改):

for (let i = 0; i < 5; i++) {
  start(i);
}

function sleep() {
  const duration = Math.floor(Math.random() * 500);
  return new Promise(resolve => setTimeout(resolve, duration));
}

function execute(id) {
  return sleep().then(() => {
    console.log("id", id);
  });
}

看到这个题目大家可以思考30s,想一想怎么去解这道题目,有兴趣的可以直接拷贝题目到一个顺手的编辑器里尝试写一写,对于程序猿来说思考的过程还是很重要的


下面开始写答案了哦~ 当然了,只是我的解题方案,大家有什么更好的方案也希望可以在评论区不吝赐教,也可以扫码添加文末二维码在微信群进行交流。准备好了吗?Baby~

以下答案只会放start函数体的更改,毕竟我们的题干只要求更改start函数体

答案一

此方案可以实现需求,但是每次调用start函数,都会清除timer,导致只有所有的调用都push完才会真正执行execute函数,代码也不优雅,算是勉强可以实现功能

注意,本例子中的start函数体内this.x是可以替换为start.x的,这样做,可避免严格模式下this为undefined而导致的异常,在非严格模式下可避免污染全局变量

function start(id) {
  if (!this.processList) this.processList = [];
  this.processList.push({ id });
  clearTimeout(this.t);
  this.t = setTimeout(() => {
    (async () => {
      let target = this.processList.shift();
      while (target) {
        await execute(target.id);
        target = this.processList.shift();
      }
    })();
  }, 0);
}

作为一个有追求的FEer怎么可以仅仅停留在方案一呢,思考~~~

答案二

经过苦苦思索,终于打通任督二脉写出了个人认为最优雅的实现方案,这个方案不需要借助定时器,思路就是Promise的链式调用即then函数

function start(id) {
  start.promises = !start.promises
    ? execute(id)
    : start.promises.then(() => execute(id));
}

到此,解题告一段落,整个解题过程还是痛苦的,但是解题完毕还是蛮有成就感的~

对前端技术交流有兴趣的同学,可以微信扫码下面的关注公众号【见闻号】或者加入前端开发者微信群,方便大家交流前端技术

本文为原创文章,仅作个人存档所用,请勿随意转载。如确有转载需求,请在转载时务必带上原文链接!码字不易,多谢合作!