调用限流 ,没走闭包的函数: 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) {
}
});
为什么??
节流
节流:请输入要搜索的内容 0
发现返回的闭包在使用立即执行,给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
}
但是限流效果没有达到,每次都会执行到回调函数。
分析: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
-
{{OrderCount}}
{{OrderCount}}
+
最终,总算执行到回调的方法log OK ,且多次点击也很限流了。 花一个上午时间调试这个问题,还是闭包知识不牢固。