Skip to content

Commit

Permalink
Merge pull request #85 from GuoXiCheng/dev-c
Browse files Browse the repository at this point in the history
update docs
  • Loading branch information
GuoXiCheng authored Oct 21, 2023
2 parents af18ba5 + 1f93702 commit e156c0d
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 24 deletions.
1 change: 1 addition & 0 deletions src/.vuepress/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export default hopeTheme({
cachePic: true,
appendBase: true,
themeColor: "#000000",
update: 'hint',
apple: {
icon: "/assets/icon/apple-icon-152.png",
statusBarColor: "black",
Expand Down
116 changes: 92 additions & 24 deletions src/develop/other/防抖和节流.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,122 @@

在一段时间后执行一次函数,如果在这个时间段内再次触发,则重新计算时间。

```js linenums="1"
function throttled(fn, delay) {
let timer = null
let starttime = Date.now()
return function () {
let curTime = Date.now()
let remaining = delay - (curTime - starttime)
let context = this
let args = arguments
clearTimeout(timer)
::: playground#ts 防抖案例交互演示

@file index.ts

```ts
/**
* 创建一个新的函数,该函数在被调用时会延迟指定的时间后再执行。
* 如果在这段时间内又被调用,则会重新计算剩余时间。
*
* @param {(...args: any[]) => void} fn - 需要被延迟的函数。
* @param {number} delay - 延迟时间,单位为毫秒。
* @returns {(...args: any[]) => void} - 返回一个新的函数,该函数在被调用时会延迟指定的时间后再执行原始函数。
*/
function throttled<T>(this: T, fn: (...args: any[]) => void, delay: number): (...args: any[]) => void {
let timer: number | null = null;
let starttime = Date.now();

// 返回一个新的函数,该函数在被调用时会延迟指定的时间后再执行原始函数
return function (this: T, ...args: any[]): void {
let curTime = Date.now();
let remaining = delay - (curTime - starttime);
let context = this;

clearTimeout(timer as number); // 取消之前的延迟调用

// 如果剩余时间已经小于或等于0,那么立即调用原始函数
// 否则,延迟剩余时间后再调用原始函数
if (remaining <= 0) {
fn.apply(context, args)
starttime = Date.now()
fn.apply(context, args);
starttime = Date.now();
} else {
timer = setTimeout(fn, remaining);
timer = setTimeout(() => {
fn.apply(context, args);
}, remaining);
}
}
}


function printTime(): void {
console.log(`Called at ${new Date().toISOString()}`);
}

// 创建一个新的函数,该函数将会在每次被调用后延迟 2000 毫秒才会真正执行 printTime 函数
const throttledPrintTime = throttled(printTime, 2000);

// 连续调用 throttledPrintTime 函数
for (let i = 0; i < 100; i++) {
throttledPrintTime();
}
```

:::

## 节流

在一段时间后执行一次函数,若在这段时间内重复触发,只执行一次。

```js linenums="1"
function debounce(func, wait, immediate) {
::: playground#ts 节流案例交互演示

let timeout;
@file index.ts

return function () {
let context = this;
let args = arguments;
```ts
/**
* 创建一个新的函数,该函数会在最后一次调用后的指定时间间隔内延迟执行原始函数。
* 如果 `immediate` 参数为 `true`,那么新的函数会立即执行原始函数,然后在指定时间间隔内不再执行。
*
* @param {T} func - 需要被延迟的原始函数。
* @param {number} wait - 延迟执行的时间(毫秒)。
* @param {boolean} immediate - 是否立即执行原始函数。
* @returns {(...args: Parameters<T>) => void} - 返回一个新的函数,该函数会在最后一次调用后的指定时间间隔内延迟执行原始函数。
*/
function debounce<T extends (...args: any[]) => any>(func: T, wait: number, immediate: boolean): (...args: Parameters<T>) => void {

let timeout: number | null;

return function (this: ThisParameterType<T>, ...args: Parameters<T>) {
const context = this;

if (timeout) clearTimeout(timeout);

if (timeout) clearTimeout(timeout); // timeout 不为null
if (immediate) {
let callNow = !timeout; // 第一次会立即执行,以后只有事件执行后才会再次触发
timeout = setTimeout(function () {
// 如果immediate为true,那么新函数在首次调用时会立即执行原始函数
const callNow = !timeout;

// 设置timeout,延迟wait毫秒后清除timeout
timeout = setTimeout(() => {
timeout = null;
}, wait)

// 如果可以立即执行,那么立即调用原始函数
if (callNow) {
func.apply(context, args)
}
}
else {
timeout = setTimeout(function () {
// 如果immediate为false,那么新函数会在最后一次调用后的wait毫秒后执行原始函数
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
}
```

// 这个函数会打印出它被调用的时间
function printTime(): void {
console.log(`Called at ${new Date().toISOString()}`);
}

// 创建一个新的函数,该函数在最后一次被调用后的 2000 毫秒才会真正调用 printTime 函数
const debouncedPrintTime = debounce(printTime, 2000, false);

// 连续调用 debouncedPrintTime 函数
for (let i = 0; i < 100; i++) {
debouncedPrintTime();
}
```

:::
3 changes: 3 additions & 0 deletions src/knowledge/防抖与节流.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
节流是指在一段时间后执行函数,若在这段时间内重复触发,则只执行一次。

举个乘电梯的例子:

第一个人走进电梯,电梯计时15秒后运行,又来第二个人走进电梯,电梯重新开始15秒计时,这是防抖。

第一个人走进电梯,电梯计时15后准时运行,这是节流。

防抖和节流都可以使用clearTimeout和setTimeout实现,目的是减少回调执行频率,节约资源。

防抖的使用场景有:搜索框输入、表单校验、窗口大小调整事件

节流的使用场景有:滚动条滚动事件、拖拽事件

0 comments on commit e156c0d

Please sign in to comment.