如何在CanJS DefineMap视图模型方法中正确使用lodash防抖函数?
在CanJS DefineMap中正确使用Lodash的_.debounce
我懂你遇到的困扰了——在CanJS的DefineMap视图模型里直接在init方法中替换方法为防抖版本,经常不会按预期工作,这主要是因为CanJS对DefineMap的方法有特殊的绑定逻辑,直接替换容易出现this指向错误或者方法被覆盖的问题。下面给你两种可靠的解决方案:
方案1:每个实例创建独立的防抖函数(推荐)
这个方法确保每个ViewModel实例都有自己的防抖函数,不会出现多个实例互相干扰的情况,同时保证this正确指向实例:
import { DefineMap } from "can"; import _ from "lodash"; export const ViewModel = DefineMap.extend({ init() { // 先绑定原始方法的this到当前实例,再包裹防抖 const boundMethod = this.myMethod.bind(this); this.myMethod = _.debounce(boundMethod, 200); }, myMethod() { // 这里的this会正确指向ViewModel实例 console.log("执行防抖后的方法", this); // 你的业务逻辑写在这里 } });
方案2:用内部方法+箭头函数包裹
如果觉得绑定this有点麻烦,也可以把业务逻辑放在一个内部方法里,然后用箭头函数包裹防抖,利用箭头函数自动继承外层this的特性:
import { DefineMap } from "can"; import _ from "lodash"; export const ViewModel = DefineMap.extend({ init() { this.myMethod = _.debounce(() => { this._myMethod(); }, 200); }, // 内部方法存放实际业务逻辑 _myMethod() { console.log("执行防抖后的方法", this); // 你的业务逻辑写在这里 } });
为什么原来的代码不生效?
你原来的写法中,_.debounce(this.myMethod, 200)里的this.myMethod虽然是实例上的方法,但防抖函数执行时的this可能没有正确绑定到实例(因为debounce默认会改变this指向),另外CanJS的DefineMap在初始化过程中可能会对方法做二次处理,导致你替换的防抖版本被覆盖。上面的两种方案都避开了这些问题。
内容的提问来源于stack exchange,提问作者Cherif BOUCHELAGHEM
相关产品推荐
相关产品推荐

