欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

有趣的面试题系列(一)

程序员文章站 2022-07-07 10:34:34
...

1.使用setTimeout实现setInterval的功能

转载自:https://blog.csdn.net/jameszhufu/article/details/81774431

timeFuction();

function timeFunction(){
    
    var timer = setTimeOut(function(){
        timeFuction();
        clearTimeOut(timer)
    },2000);
}

2.EventLoop问题

console.log('script start');

async function async1(){
    await async2();
    console.log('async1 end');
}

async function async2(){
    console.log('async2 end');
}

async1();

setTimeout(function(){
    console.log('setTimeout');
},0)

new Promise(resolve=>{
    console.log('Promise');
    resolve();
}).then(function(){
    console.log('promise1')
}).then(function(){
    console.log('promise2')
})

console.log('script end')

执行结果:

  1. scirpt start
  2. async2 end
  3. Promise
  4. script end
  5. promise1
  6. promise2
  7. async1 end
  8. setTimeout  

详解

首先先来解释下上述代码的 async 和 await 的执行顺序。当我们调用 async1 函数时,会马上输出 async2 end,并且函数返回一个 Promise,接下来在遇到 await的时候会就让出线程开始执行 async1 外的代码,所以我们完全可以把 await 看成是让出线程的标志。

然后当同步代码全部执行完毕以后,就会去执行所有的异步代码,那么又会回到 await 的位置执行返回的 Promise 的 resolve 函数,这又会把 resolve 丢到微任务队列中,接下来去执行 then 中的回调,当两个 then 中的回调全部执行完毕以后,又会回到 await 的位置处理返回值,这时候你可以看成是 Promise.resolve(返回值).then(),然后 await 后的代码全部被包裹进了 then 的回调中,所以 console.log('async1 end') 会优先执行于 setTimeout。
————————————————
版权声明:本文为CSDN博主「itKingOne」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/itKingOne/article/details/86502910

3.React setState  异步操作

class Example extends React.Component {
  constructor() {
    super();
    this.state = {
      val: 0
    };
  }
  
  componentDidMount() {
    this.setState({val: this.state.val + 1});
    console.log(this.state.val);    // 第 1 次 log

    this.setState({val: this.state.val + 1});
    console.log(this.state.val);    // 第 2 次 log

    setTimeout(() => {
      this.setState({val: this.state.val + 1});
      console.log(this.state.val);  // 第 3 次 log

      this.setState({val: this.state.val + 1});
      console.log(this.state.val);  // 第 4 次 log
    }, 0);
  }

  render() {
    return null;
  }
};

执行结果: 0, 0, 2, 3。

总结起来就是这样:

  • this.setState首先会把state推入pendingState队列中
  • 然后将组件标记为dirty
  • React中有事务的概念,最常见的就是更新事务,如果不在事务中,则会开启一次新的更新事务,更新事务执行的操作就是把组件标记为dirty。
  • 判断是否处于batch update
  • 是的话,保存组建于dirtyComponent中,在事务结束的时候才会通过 ReactUpdates.flushBatchedUpdates 方法将所有的临时 state merge 并计算出最新的 props 及 state,然后将其批量执行,最后再关闭结束事务。
  • 不是的话,直接开启一次新的更新事务,在标记为dirty之后,直接开始更新组件。因此当setState执行完毕后,组件就更新完毕了,所以会造成定时器同步更新的情况。

转载地址:https://www.jianshu.com/p/b38a7a4eda2b

4.手写 防抖 和节流函数

//  防抖 : 限制一段时间内不触发
function 防抖(fn,t){
    var timer=null;
    return function(){
        var context=this;
        var args = arguments;
        if(timer) clearTimeout(timer);
        timer=setTimeout(function(){
            fn.apply(context,args);
            clearTimeout(timer);
            timer=null;
        },t)
    }
}

//  节流 : 限制一段时间内触发次数
function 节流(fn,t){
    var timer=null;
    return function(){
        var context=this;
        var args = argument;
        if(timer) return;
        timer=setTimeOut(function(){
            fn.apply(context,args);
            clearTimeOut(timer);
            timer=null;
        },t)
    }
}