实现数组扁平化
要求不使用递归来展平数组,可以使用以下代码来展平数组,同时不改变数组的元素位置
function flattenArray(arr) {
const result = [];
const stack = [...arr];
while (stack.length) {
const next = stack.pop();
if (Array.isArray(next)) {
stack.push(...next);
} else {
result.unshift(next);
}
}
return result;
}
在这个示例中,我们使用一个 while 循环和一个辅助栈来展平数组。我们不断地从栈中弹出元素,如果弹出的元素是数组,就将其内容推入栈中;如果不是数组,就将其添加到结果数组的开头。这样就可以展平数组,同时不改变数组的元素位置,并且不使用递归。
settimeout 模拟 setInterval
setInterval 的作用是每隔一段指定时间执行一个函数,但是这个执行不是真的到了时间立即执行,它真正的作用是每隔一段时间将事件加入事件队列中去,只有当当前的执行栈为空的时候,才能去从事件队列中取出事件执行。所以可能会出现这样的情况,就是当前执行栈执行的时间很长,导致事件队列里边积累多个定时器加入的事件,当执行栈结束的时候,这些事件会依次执行,因此就不能到间隔一段时间执行的效果。
针对 setInterval 的这个缺点,我们可以使用 setTimeout 递归调用来模拟 setInterval,这样我们就确保了只有一个事件结束了,我们才会触发下一个定时器事件,这样解决了 setInterval 的问题。
实现思路是使用递归函数,不断地去执行 setTimeout 从而达到 setInterval 的效果
javascript
复制代码
作者:CUGGZ
链接:juejin.cn/post/694613…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
function mySetInterval(func, delay) {
let timer = {
flag: true
};
function interval() {
if (timer.flag) {
// 这段代码的目的是确保即使函数执行时间超过了设定的间隔时间,下一个定时器的触发时间也会按照设定的间隔来进行,从而避免定时器间隔累积。这样可以更准确地模拟 setInterval 的行为,并避免由于函数执行时间较长而导致的定时器堆积问题。
let startTime = Date.now();
func();
let endTime = Date.now();
let actualDelay = endTime - startTime;
let remainingTime = Math.max(0, delay - actualDelay);
// 递归调用
setTimeout(interval, remainingTime);
}
}
// 启动定时器
setTimeout(interval, delay);
return timer;
}
// 用法
function sayHello() {
console.log('Hello');
}
let timer = mySetInterval(sayHello, 1000);
// 5秒后停止定时器
setTimeout(function() {
timer.flag = false;
}, 5000);