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




  
  节流


节流:请输入要搜索的内容 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
}

问题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

-
        {{OrderCount}}
        {{OrderCount}}
        +

最终,总算执行到回调的方法log OK ,且多次点击也很限流了。 花一个上午时间调试这个问题,还是闭包知识不牢固。

js 小程序限流函数 return闭包函数执行不了_第1张图片

你可能感兴趣的:(javascript,小程序,前端,限流)