Home Do not allow call of a subscriber with the same argument twice until the first is done

# Do not allow call of a subscriber with the same argument twice until the first is done

bolzano
1#
bolzano Published in 2018-02-12 15:10:47Z
 I am currently experimenting with beacons and I want to get the rssi measurements of the beacons in order to trigger an alarm function. My problem is the following: alarm function is triggered multiple times once the subscriber is called What I want: Do not allow alarm to execute more than once with the previous argument. For example if the alarm function is called with argument 'x' then someone cannot call alarm with 'x' but can call it with 'y' in order to avoid multiple pushes to the database. My code (I am using noble for beacons and firebase for my db): // alarm script import { config, Device, db, auth, productsRef } from './index'; import * as noble from 'noble'; import * as firebase from 'firebase'; var acquiredRef = db.ref('acquired'); function condition(p) { // a boolean function that does something } function alarm (address) { console.log('Alarm!'); let incident = { date : Date(), uuid : address, } db.ref('alarms').push(incident); } if (require.main === module) { noble.on('stateChange', function (state) { if (state === 'poweredOn') noble.startScanning([], true); else noble.stopScanning(); }); noble.on('discover', function(peripheral) { peripheral.address = peripheral.address.toUpperCase(); if (condition(peripheral)) { // query acquiredRef.orderByChild('uuid').equalTo(peripheral.address).once('value') .then(snap => { if(snap.val() == null) alarm(peripheral.address); }).catch(err => console.log(err)) } }); }  I tried using queues and async-lock without success. It works the first time alarm is called and then has the same behaviour as above. Thanks in advance
slinhart
2#
 If you are only interested in making sure the alarm function doesn't get called twice (or more) times in a row with the same arguments (in this case just the string 'address') you could just store a variable and compare you most recent argument to your current argument. If the arguments are the same, don't execute the rest of the function. let previousAddress = null; function alarm (address) { if (address === previousAddress) { return; // skip } console.log('Alarm!'); let incident = { date : Date(), uuid : address, } db.ref('alarms').push(incident); previousAddress = address; // update previous argument } 
 I had a problem similar to yours. On my case an simple elapsed time variable did the trick. This is necessary because the discover callback executes multiple times on the same peripheral. Take a look at it. noble.on('discover', function(peripheral) { if (peripheral.advertisement.localName == 'FinishLine') { if (lastDetection == null) { alert(); } else { if ((Date.now() - lastDetection) / 1000 > 2) { alert(); } } } });  Because of the asynchronous firebase call behavior you can not rely on the query. A pause of 2 or more seconds like I did might solve your problem.