lodash debounce not-working (I use it wrongly?), function called multiple times
我的目标很简单:
我有一个谷歌地图画布。用户可以拖动地图,程序会自动下载地图中心周围的事件(并绘制标记)。
我有 plugin.google.maps.event.CAMERA_CHANGE 事件的监听器。问题是,这个监听器会触发多次。含义:从您在画布上点击手指的那一刻起-> 在画布上拖动-> 到您抬起手指的那一刻……事件多次触发。不只是当你抬起手指的时候。
显然它有一个每 N 毫秒触发一次的观察者。
我不希望我的代码在这些临时 camera_changes 期间从服务器绘图标记执行昂贵的数据下载。我只想在用户停止拖动后才这样做。这意味着:在 5 秒内收到最后一个相机更改事件(我认为最慢的用户需要 5 秒才能从画布的角落拖动到对角)。
显然我转向 debounce 来满足这种需求。但这似乎不起作用。我可以从日志中看到 (X1, X2).... 该函数被多次调用(大约 3 到 4 次,取决于您在画布上拖动的速度)。
确实,它们只有在我停止拖动后才会被调用。但是,它们被连续调用。全部3-4个。调用之间有 5 秒的延迟。
这不是我所期望的。我还向 .cancel 方法添加了调用(我认为这是多余的......,因为如果我理解正确,去抖动应该已经处理了它;在超时内取消临时调用)。
我也尝试过油门(我认为从概念上讲不是答案。去抖动应该是答案)。无论如何,油门也有同样的问题。
所以,我的问题是:我在哪里做错了(在使用 lodash 的去抖)?
谢谢!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | var currentPosition = initialPosition(); drawMarkersAroundCenter(map, currentPosition); var reactOnCameraChanged = function(camera) { console.log('X1'); console.log('-----'); console.log(JSON.stringify(camera.target)); console.log(JSON.stringify(currentPosition)); console.log('-----'); if (camera.target.lat == currentPosition.lat && camera.target.lng == currentPosition.lng) { return; } currentPosition = camera.target; drawMarkersAroundCenter(map, currentPosition); } var debouncedReactOnCameraChange = lodash.debounce(reactOnCameraChanged, 5000, { 'leading': false, 'trailing': true }); map.on(plugin.google.maps.event.CAMERA_CHANGE, function(camera) { debouncedReactOnCameraChange.cancel(); debouncedReactOnCameraChange(camera); }); |
--- 更新 ---
我尝试了一个在 nodejs 控制台上使用 debounce 的非常简化的场景,它按我的预期工作。我什至没有在下面的代码中调用 .cancel。那么上面的代码有什么问题呢?在下图中,我看不出这个简化的代码有什么不同。
更新
我尝试使用这种方法而不是"reactOnCameraChanged":
1 2 3 4 5 6 7 8 | var dude = function(camera) { console.log('dude'); } var debouncedReactOnCameraChange = lodash.debounce(dude, 5000, { 'leading': false, 'trailing': true }); |
我还删除了对 .cancel:
的调用
1 2 3 4 | map.on(plugin.google.maps.event.CAMERA_CHANGE, function(camera) { //debouncedReactOnCameraChange.cancel(); debouncedReactOnCameraChange(camera); }); |
我可以看到 'dude' 在这 5 秒内只打印了一次....所以..,我在 reactOnCameraChanged 中所做的事情正在造成干扰......不知何故....
解决:
请参阅下面的答案。
此代码有效:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | var currentPosition = latLng; drawMarkersAroundCenter(map, currentPosition); var debouncedReactOnCameraChange = lodash.debounce(function(camera) { console.log('reactOnCameraChanged: ' + JSON.stringify(currentPosition)); drawMarkersAroundCenter(map, currentPosition); }, 3000, { 'leading': false, 'trailing': true }); map.on(plugin.google.maps.event.CAMERA_CHANGE, function(camera) { console.log('CAMERA_CHANGE'); if (camera.target.lat == currentPosition.lat && camera.target.lng == currentPosition.lng) { console.log('same camera spot'); return; } console.log('different camera spot'); currentPosition = camera.target; debouncedReactOnCameraChange(camera); }); |