Skip to content

Commit

Permalink
修订JavaScript专题之跟着underscore学防抖
Browse files Browse the repository at this point in the history
  • Loading branch information
mqyqingfeng committed Jun 18, 2017
1 parent c2a5ff6 commit b6205e5
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 73 deletions.
File renamed without changes
Original file line number Diff line number Diff line change
Expand Up @@ -165,44 +165,56 @@ function debounce(func, wait) {
}
```

## 返回值
到此为止,我们修复了两个小问题:

1. this 指向
2. event 对象

## 立刻执行

再注意一个小点,getUserAction 函数可能是有返回值的,所以我们也要返回函数的执行结果
这个时候,代码已经很是完善了,但是为了让这个函数更加完善,我们接下来思考一个新的需求。

这个需求就是:

我不希望非要等到事件停止触发后才执行,我希望立刻执行函数,然后等到停止触发 n 秒后,才可以重新触发执行。

想想这个需求也是很有道理的嘛,那我们加个 immediate 参数判断是否是立刻执行。

```js
// 第四版
function debounce(func, wait) {
function debounce(func, wait, immediate) {

var timeout, result;

return function () {
var context = this;
var args = arguments;

clearTimeout(timeout)
timeout = setTimeout(function(){
result = func.apply(context, args)
}, wait);

return result;
if (timeout) clearTimeout(timeout);
if (immediate) {
// 如果已经执行过,不再执行
var callNow = !timeout;
timeout = setTimeout(function(){
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
else {
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
}
```

到此为止,我们修复了三个小问题:

1. this 指向
2. event 对象
3. 返回值

## 立刻执行
再来看看使用效果:

这个时候,代码已经很是完善,但是为了让这个函数更加完善,我们接下来思考一个新的需求。
![debounce 第四版](https://github.com/mqyqingfeng/Blog/raw/master/Images/debounce/debounce-4.gif)

这个需求就是:
## 返回值

我不希望非要等到事件停止触发后才执行,我希望立刻执行函数,然后等到停止触发 n 秒后,才可以重新触发执行。

想想这个需求也是很有道理的嘛,那我们加个 immediate 参数判断是否是立刻执行。
此时注意一点,就是 getUserAction 函数可能是有返回值的,所以我们也要返回函数的执行结果,但是当 immediate 为 false 的时候,因为使用了 setTimeout ,我们将 func.apply(context, args) 的返回值赋给变量,最后再 return 的时候,值将会一直是 undefined,所以我们只在 immediate 为 true 的时候返回函数的执行结果。

```js
// 第五版
Expand All @@ -225,19 +237,14 @@ function debounce(func, wait, immediate) {
}
else {
timeout = setTimeout(function(){
result = func.apply(context, args)
func.apply(context, args)
}, wait);
}

return result;
}
}
```

再来看看使用效果:

![debounce 第五版](https://github.com/mqyqingfeng/Blog/raw/master/Images/debounce/debounce-5.gif)

## 取消

最后我们再思考一个小需求,我希望能取消 debounce 函数,比如说我 debounce 的时间间隔是 10 秒钟,immediate 为 true,这样的话,我只有等 10 秒后才能重新触发事件,现在我希望有一个按钮,点击后,取消防抖,这样我再去触发,就可以又立刻执行啦,是不是很开心?
Expand Down Expand Up @@ -265,7 +272,7 @@ function debounce(func, wait, immediate) {
}
else {
timeout = setTimeout(function(){
result = func.apply(context, args)
func.apply(context, args)
}, wait);
}
return result;
Expand Down
30 changes: 19 additions & 11 deletions demos/debounce/debounce5.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* 返回函数的返回值
* 添加immediate参数,让函数能够立刻执行,仅当事件停止触发n秒后,才能重新触发
*/
var count = 1;
var container = document.getElementById('container');
Expand All @@ -8,22 +8,30 @@ function getUserAction(e) {
container.innerHTML = count++;
};

container.onmousemove = debounce(getUserAction, 1000);
container.onmousemove = debounce(getUserAction, 1000, true);

// 第四版
function debounce(func, wait) {
var timeout, result;
function debounce(func, wait, immediate) {

var timeout, result;

return function () {
var context = this;
var args = arguments;

clearTimeout(timeout)
timeout = setTimeout(function(){
result = func.apply(context, args)
}, wait);

return result;
if (timeout) clearTimeout(timeout);
if (immediate) {
// 如果已经执行过,不再执行
var callNow = !timeout;
timeout = setTimeout(function(){
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
else {
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
}
}
56 changes: 23 additions & 33 deletions demos/debounce/debounce6.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,30 @@
/**
* 添加immediate参数,让函数能够立刻执行,仅当事件停止触发n秒后,才能重新触发
* 添加函数返回值
*/
var count = 1;
var container = document.getElementById('container');

function getUserAction(e) {
container.innerHTML = count++;
};

container.onmousemove = debounce(getUserAction, 1000, true);

// 第五版
function debounce(func, wait, immediate) {

var timeout, result;

return function () {
var context = this;
var args = arguments;

if (timeout) clearTimeout(timeout);
if (immediate) {
// 如果已经执行过,不再执行
var callNow = !timeout;
timeout = setTimeout(function(){
timeout = null;
}, wait)
if (callNow) result = func.apply(context, args)
}
else {
timeout = setTimeout(function(){
result = func.apply(context, args)
}, wait);
}


return result;
}
var timeout, result;

return function () {
var context = this;
var args = arguments;

if (timeout) clearTimeout(timeout);
if (immediate) {
// 如果已经执行过,不再执行
var callNow = !timeout;
timeout = setTimeout(function(){
timeout = null;
}, wait)
if (callNow) result = func.apply(context, args)
}
else {
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
return result;
}
}
2 changes: 1 addition & 1 deletion demos/debounce/debounce7.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function debounce(func, wait, immediate) {
}
else {
timeout = setTimeout(function(){
result = func.apply(context, args)
func.apply(context, args)
}, wait);
}

Expand Down

0 comments on commit b6205e5

Please sign in to comment.