Mapbox GL JS,在mousemove事件处理器内部使用setTimeout时,遇到事件对象在延迟执行的异步函数中无法访问到原始的event对象属性event.features

发现问题

在开发webmap时遇到一个需求,即鼠标在Mapbox GL JS创建的地图中移动时不执行mousemove事件,等鼠标停止后执行。那么很容易想到的代码是下面这样的。

let timeoutfn;

function throttleMousemove(e){
   
	console.log(e.features); // 输出 features
	if (timeoutfn) {
   
		clearTimeout(timeoutfn);
	}
	timeoutfn = setTimeout(function () {
   
		console.log(e.features); // 输出 undefined
	}, 50);
}
// 添加mousemove事件
map.on("mousemove", '测试图层', throttleMousemove);

很简单的实现,在setTimeout方法中获取Event对象,然后输入该对象的features属性。

但是,setTimeout中的console.log(e.features)输出的是 undefined,没错,确定是undefined

解决问题

因为业务代码比较复杂,首先想到的是数据在上下文变更了,然后排查上下文业务代码,各种业务逻辑都注释掉,也没发现问题,最后精简代码,只有上面的简单的监听事件,问题还是存在。

难道,Mapbox GL JS可能需要时间来解析鼠标所在位置下的地图特性(features),这些特性可能不是立即可用的?这也不可能啊,明显可以知道setTimeout内部的执行时间比外部要靠后,外部可以获取,内部不可能获取不到。

难道因为数据量大被垃圾回收机制自动给回收了?这个更不可能了,setTimeout 内部可以获取到e对象的,没道理只回收features属性。这个时候考虑是不是e.features被Mapbox GL JS库的开发者销毁了?

难道这是Mapbox GL JS内部机制的问题?Mapbox GL JS可能在事件处理的某些阶段对事件对象进行了修改或清理操作,特别是在处理大量数据交互时,为了性能考虑,可能释放了非必需的资源?这确实也可能导致某些属性在异步回调中不可用。

然后我去扒了Mapbox GL JS的源码,确认了我的想法,确实是Mapbox GL JS内部机制的问题,在事件执行完之后,确实将e.features给回收了。贴一下部分源码:

_createDelegatedListener(type: keyof MapEventType | string, layerId: string, listener: Listener): {
   
        layer: string;
        listener: Listener;
        delegates: 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值