js 小程序限流函数 return闭包函数执行不了
问题:
调用限流 ,没走闭包的函数: checkBalanceReq()
loadsh.js
-
// 限流
-
const throttle = (fn, context, interval) => {
-
console.log(">>>>cmm throttle", context, interval)
-
let canRun = true; // 通过闭包保存一个标记
-
if (typeof fn != "function") {
-
console.log("fn 变量需要是函数")
-
return;
-
}
-
interval = interval ? interval : 500
-
console.log(">>开始return", interval)
-
return function (e) {//匿名函数
-
console.log(">>限流return")
-
let args = arguments
-
console.log(">>>args", args)
-
if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
-
canRun = false; // 立即设置为false
-
setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
-
fn.apply(context, arguments);
-
// 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
-
canRun = true;
-
}, 500);
-
};
-
}
-
-
module.exports = {
-
throttle: throttle,
-
}
页面调用:点击加减号调用限流方法
-
const {throttle} = require("../../utils/loadshMy");
-
-
Page({
-
data: {
-
test: "测试",
-
OrderCount: 0,
-
list: [1, 2, 3, 4, 5, 6, 7, 8, 9]
-
},
-
-
onChangeNums(e) {
-
if (e.target.dataset.add) {
-
this.setData({
-
OrderCount: this.data.OrderCount 2
-
})
-
} else {
-
this.setData({
-
OrderCount: this.data.OrderCount - 2
-
})
-
}
-
console.log(">>>开始throtthle", this)
-
throttle.apply(this, [this.checkBalanceReq, this, 660])
-
},
-
-
checkBalanceReq() {
-
console.log(">>||----------------执行余额查询")
-
}
-
onLoad: function (options) {
-
}
-
});
为什么??
在浏览器HTML ok
-
<!DOCTYPE html>
-
<html lang="en">
-
<head>
-
<meta charset="UTF-8">
-
<title>节流</title>
-
</head>
-
<body>
-
<div>
-
<h1>节流:请输入要搜索的内容 <span>0</span></h1>
-
<button type="button">点击加1</button>
-
<script>
-
//节流:在规定时间内, 只触发或者只执行一次对应函数,减少函数的执行。即:频繁触发改为少量触发
-
let btn = document.querySelector('button')
-
var count = 0
-
// btn.onclick = function () {
-
// count ;
-
// document.querySelector('span').innerText = count
-
// }
-
-
-
// 简单实现-settimeout
-
function throttle(fn, interval, context) {
-
let canRun = true; // 通过闭包保存一个标记
-
interval = interval | 500
-
return function () {
-
console.log(">>interval=" interval, context)
-
if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
-
canRun = false; // 立即设置为false
-
setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
-
fn.apply(this, arguments);
-
// 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
-
canRun = true;
-
}, interval);
-
};
-
}
-
-
function sayHi(e) {
-
console.log(e.target.innerWidth, e.target.innerHeight);
-
console.log(count 12)
-
pr()
-
}
-
-
function pr() {
-
console.log(count )
-
}
-
-
window.addEventListener('resize', throttle(sayHi));
-
btn.addEventListener('click', throttle(sayHi, 500, this));
-
</script>
-
</div>
-
</body>
-
</html>
解决:
发现返回的闭包在使用立即执行,给return的函数用2个括号封装起来()()
因为return的是function,外部访问的时候必须加上括号,不然得到的是function本身的内容,但不执行。如果要得到return后的函数,就是要得到throttle()(),而不是throttle(), 所以return的函数必须加上括号。
最终代码:
loadsh.js
-
// 简单实现-settimeout
-
const throttle = (fn, context, interval) => {
-
console.log(">>>>|--------15 ------- cmm throttle", context, fn)
-
let canRun = true; // 通过闭包保存一个标记
-
if (typeof fn != "function") {
-
console.log("fn 变量需要是函数")
-
return;
-
}
-
interval = interval | 500
-
console.log(interval)
-
-
return (function () {//匿名函数
-
console.log(">>限流return")
-
let args = arguments
-
console.log(">>>args", args)
-
if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
-
canRun = false; // 立即设置为false
-
setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
-
fn.apply(context, arguments);
-
// 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
-
canRun = true;
-
}, interval);
-
})();
-
}
-
-
module.exports = {
-
throttle: throttle
-
}
问题2:以上代码能执行到回调函数:checkBalanceReq()
但是限流效果没有达到,每次都会执行到回调函数。
分析:wxml页面调用的地方,每次都是一个新的变量,需要做成保存唯一的封包函数。
throttle不要直接用2个括号()(),返回闭包函数
-
// 简单实现-settimeout
-
const throttle = (fn, context, interval) => {
-
console.log(">>>>|--------15 ------- cmm throttle", context, fn)
-
let canRun = true; // 通过闭包保存一个标记
-
if (typeof fn != "function") {
-
console.log("fn 变量需要是函数")
-
return;
-
}
-
interval = interval | 500
-
console.log(interval)
-
-
return function () {//匿名函数
-
console.log(">>限流return")
-
let args = arguments
-
console.log(">>>args", args)
-
if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
-
canRun = false; // 立即设置为false
-
setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
-
fn.apply(context, arguments);
-
// 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
-
canRun = true;
-
}, interval);
-
};
-
}
-
-
module.exports = {
-
throttle: throttle
-
}
小程序页面对应 js: 页面增加一个变量balanceCallFn,来存储返回的封包函数,不为空的情况直接执行,就不会每次冲掉timer了。
-
const {throttle} = require('../../utils/loadshMy')
-
var balanceCallFn
-
Page({
-
data: {
-
test: "测试",
-
OrderCount: 0,
-
list: [1, 2, 3, 4, 5, 6, 7, 8, 9]
-
},
-
onswitch(e) {
-
console.log(e)
-
this.setData({
-
showinput: true,
-
focus: true,
-
current: e.target.dataset.index,
-
})
-
},
-
onChangeNums(e) {
-
if (e.target.dataset.add) {
-
this.setData({
-
OrderCount: this.data.OrderCount 2
-
})
-
} else {
-
this.setData({
-
OrderCount: this.data.OrderCount - 2
-
})
-
}
-
console.log(">>>开始throtthle", this)
-
if(!balanceCallFn){
-
balanceCallFn=throttle.apply(this, [this.checkBalanceReq, this, 660])
-
}
-
balanceCallFn();
-
},
-
checkBalanceReq() {
-
console.log(">>||----------------执行余额查询")
-
},
-
bindinputnum(e) {
-
console.log(">>>失去点时")
-
this.setData({
-
showinput: false
-
})
-
},
-
onLoad: function (options) {
-
}
-
});
wxml
-
<text class="minus" data-minus bindtap="onChangeNums" data-index="{{index}}">-</text>
-
<text type="number" class="number" bindtap="onswitch" wx:if="{{!showinput}}">{{OrderCount}}</text>
-
<input type="number" class="number" >{{OrderCount}}</input>
-
<text class="add" bindtap="onChangeNums"> </text>
最终,总算执行到回调的方法log OK ,且多次点击也很限流了。 花一个上午时间调试这个问题,还是闭包知识不牢固。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhiahhbc
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
微信运动停用后别人还能看到步数吗
PHP中文网 07-22