js 小程序限流函数 return闭包函数执行不了

这篇具有很好参考价值的文章主要介绍了js 小程序限流函数 return闭包函数执行不了。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题:

调用限流 ,没走闭包的函数:  checkBalanceReq()

业务逻辑:

1.限流函数:loadshMy.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; 
    canRun = false; // 立即设置为false
    setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
      fn.apply(context, arguments);
      canRun = true;
    }, 500);
  };
}

module.exports = {
  throttle: throttle,
}

2.页面调用:点击加减号调用限流方法,

js 小程序限流函数 return闭包函数执行不了,javascript,小程序,前端,限流

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) {
  }
});

 运行结果是:怎么都调不到checkBalanceReq()这个方法。为什么??

3.测试:在浏览器HTML运行差不多的逻辑,运行回调是 OK的, WHY?
<!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
 
    function throttle(fn, interval, context) {
      let canRun = true; 
      interval = interval | 500
      return function () {
        console.log(">>interval=" + interval, context)
        if (!canRun) return;
        canRun = false;
        setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
          fn.apply(this, arguments);
          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);
  })(); // 加()让throttle函数够执行
}

module.exports = {
  throttle: throttle
}

新问题2:

以上业务代码能执行到回调函数:checkBalanceReq(),但是限流效果没有达到,每次一点击按钮,都会执行到回调函数。

问题分析:

wxml页面调用的地方,每次都是一个新的变量,需要做成保存唯一的封包函数。

throttle不要直接用2个括号()(), 返回闭包函数用一个当前页面的全局变量存起来。

 最后完整的OK代码:

//    简单实现-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了。

(throttle.apply()让调用内部this指向当前页面this)

.js 

const {throttle} = require('../../utils/loadshMy')
var balanceCallFn
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)
    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>-</text>
 <input type="number" class="number" >{{OrderCount}}</input>
  <text class="add" data-add bindtap="onChangeNums">+</text>

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

js 小程序限流函数 return闭包函数执行不了,javascript,小程序,前端,限流

PS:

节流函数和防抖函数区别与使用的场景

1.什么时候会用到节流函数和防抖函数?
调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位(防抖)
文本编辑器实时保存,当无任何更改操作一秒后进行保存(防抖)
按钮重复多次点击(节流)
百度搜索框,搜索联想功能(节流)


2.防抖函数和节流函数的区别
防抖函数是在单位时间(>1)随便触发多少次事件,只要这次触发的时间与上次触发的时间只差不到1s,都不执行;所以执行一次的时候离触发开始可能已经过了2s,3s,4s都有可能了。


节流函数是在单位时间(>1)随便触发多少次事件,只要过了1s,就会执行一次

两个函数都能达到防止重复触发的功能。但是函数防抖是 n秒后延迟执行;而函数节流是立马执行,n秒后再立马执行。

具体的使用主要看需求:

当我们只需要处理最后一次触发事件时,用函数防抖
当事件触发过于频繁,我们需要限制事件处理程序的调用频率时,用函数节流 文章来源地址https://www.toymoban.com/news/detail-655908.html

到了这里,关于js 小程序限流函数 return闭包函数执行不了的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包