工具相关
防抖
/**
* 函数防抖
* 1. 返回防抖的新函数
* 2. 原函数中的this可以正常使用
* 3. 原函数的参数可以正常使用
* @param {Function} fn 函数
* @param {Number} delay 延迟时间
*/
function debounce(fn, delay = 0) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
// 保证fn的this为调用debounce的this
fn.apply(this, args);
}, delay);
};
}节流
/**
* 函数节流
* 1. 返回节流的新函数
* 2. 原函数中的this可以正常使用
* 3. 原函数的参数可以正常使用
* @param {Function} fn 函数
* @param {Number} delay 延迟时间
*/
function throttle(fn, delay = 0) {
let timer = undefined;
return function (...args) {
if (timer !== undefined) {
return;
} else {
timer = setTimeout(() => {
fn.apply(this, args);
timer = undefined;
}, delay);
}
};
}setTimeout和setInterval
setInterval
/**
* 使用setTimeout实现setInterval
* @param {*} fn 回调函数
* @param {*} delay 延时
* @returns 停止函数
*/
function mySetInterval(fn, delay) {
let timer = null;
function inner() {
fn();
timer = setTimeout(inner, delay);
}
timer = setTimeout(inner, delay);
return {
clear() {
clearTimeout(timer);
},
};
}setTimeout
/**
* 使用setInterval实现setTimeout
* @param {*} fn 回调函数
* @param {*} delay 延时
*/
function mySetTimeout(fn, delay) {
let timer = setInterval(() => {
fn();
clearInterval(timer);
}, delay);
}sleep
使用promise模拟
/**
* 使用promise模拟sleep函数
* @param {*} t 休眠时间,单位:ms
*/
function sleep1(t) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, t);
});
}
async function test1() {
console.log("开始");
await sleep1(2000);
console.log("结束");
}缺点: 使用时需要借助async和await才能阻塞后面的代码休眠
借助时间戳
/**
* 基于时间戳实现
*/
function sleep2(t) {
const end = Date.now() + t;
while (Date.now() < end) {
continue;
}
}洋葱模型
class Onion {
tasks = [];
isRunning = false;
curIndex = 0;
// 运行下一个任务,由于传递给外部函数,所以需要箭头函数绑定当前this
next = async () => {
++this.curIndex;
await this.runATask();
}
addTask(task) {
this.tasks.push(task);
}
run() {
if (this.isRunning || this.tasks.length <= 0) {
return;
}
this.isRunning = true;
this.runATask();
}
async runATask() {
if (this.curIndex >= this.tasks.length) {
this.reset();
return;
}
const i = this.curIndex;
const task = this.tasks[this.curIndex];
await task(this.next);
const j = this.curIndex;
if (i === j) {
await this.next();
}
}
reset() {
this.tasks.length = 0;
this.curIndex = 0;
this.isRunning = false;
}
}
const test = () => {
const onion = new Onion();
onion.addTask((next) => {
console.log(1);
next();
console.log(1);
});
onion.addTask((next) => {
console.log(2);
next();
console.log(2);
});
onion.addTask(() => {
console.log(3);
});
onion.run();
};
test()贡献者
版权所有
版权归属:wynnsimon
