有趣的面试题系列(一)
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')
执行结果:
- scirpt start
- async2 end
- Promise
- script end
- promise1
- promise2
- async1 end
- 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)
}
}
上一篇: 有趣的BAT逻辑面试题分享
下一篇: Magento付款方式的判断
推荐阅读
-
JavaScript面试题:一道关于变量提升的题
-
spring-boot-2.0.3不一样系列之源码篇 - run方法(三)之createApplicationContext,绝对有值得你看的地方
-
【JavaScript系列】你应掌握的JavaScript之函数(一)
-
小米家族中的一代神机:Redmi Note系列销量突破1.1亿台
-
Redis系列(一):Redis的简介与安装
-
苹果彻底无视Intel的节奏:下一代Mac系列将首发M2 性能更强劲
-
一道关于php变量引用的面试题
-
.net必问的面试题系列之面向对象
-
我经历的一些Android面试题及答案
-
让Python给你讲笑话、段子,一个有趣的Python案例