React-native debugger runs faster than no debugging - javascript

I'm using react-native 0.63 and doing a simple 1sec interval when I mount a component.
e.g.
useEffect(() => {
// Start elapsed ticker
const levelTicker = setInterval(() => {
console.log('TICK...')
setSeconds((s) => s + 1)
}, 1000)
return () => {
console.log('CLEARING INTERVAL')
clearInterval(levelTicker)
}
}, [])
When I run the app without debugger on, the app will render the timer correctly (1 second every render). But when I activate the debugger, it runs much more quickly--0.00001s every render--which makes it almost impossible to click buttons or do whatever on the app. The same thing happens when trying to onPress on Buttons that has onLongPress. It will run so fast, that even a quick tap will trigger the onLongPress.
Any clues how to make at least to run at normal speed? Thanks in advance.
Device:
OnePlus 7T, Android 10

Related

setInterval triggering faster than set

I am trying to build a dinosaur running game in React much like google chrome's.
My idea is that I will run a function at the exact moment the object is suppose to hit the dinosaur, around 3 seconds
function check4Death() {
if (playerClass !== '') {
console.log('safe')
}
else {
console.log('nope')
clearInterval()
}
}
setInterval(check4Death, 3000)
This function checks to see if the player is currently in the air
As my method of jumping is adding and then removing a class from my playerClass object
function Jump() {
setPlayerClass('jump')
setTimeout(() => {
setPlayerClass('')
}, 500);
}
Instead of the function telling me either safe or nope every three seconds, I get this
I am very confused as to why this is happening, I have a link to my full code here

Not able to clear my setInterval in Ionic

I have an IONIC 4 application where I need to call an api every 20 seconds and if the user moves to other page need to stop calling that api. I am able to make the api call at every 20 seconds but not able to stop it when I move to some other page. Here is my code below, may I know where I went wrong?
rateTimer:any;
constructor(private loginServiceService: LoginServiceService) {
this.loginServiceService.getappData();
this.rateTimer=setInterval(() => {
this.loginServiceService.getappData();
}, 10000);
}
// When I move to other page, I clear the setInterval from here
ngOnDestroy() {
clearInterval(this.rateTimer);
}
As far as I know Ionic has a cache for page-navigation which is why ngOnDestroy/ngOnInit will not always work. However, there's ionViewDidLeave which should definitely fire, once the current page is moved away from (see https://ionicframework.com/docs/api/router-outlet#life-cycle-hooks for more details):
export class YourComponent {
ionViewDidLeave() {
// Do actions here
}
}

React Native background timer never stops

I'm building an app that has a timer to request geolocation while the timer is active. For a timer I'm using react-native-background-timer. Which is kind of working, but not exactly as I want.
With this piece of code:
BackgroundTimer.runBackgroundTimer(() => {
console.log('tic');
},
1000);
the timer is stopping when the app is in the background. While with this piece of code:
const intervalId = BackgroundTimer.setInterval(() => {
console.log('tic');
}, 1000);
it runs constantly even in the background, but I'm not able to stop it. When I run BackgroundTimer.clearInterval(intervalId);, the timer still runs. Even when I leave the screen and go back to my Home screen, the timer still ticks and never stops. This is not ideal, because I need timer to run for a few minutes and then stop.
I set the timer to 1 second to update time left on the screen. I was thinking about setting a timer once for 6 minutes, but then how do I update the state every second? Making 2 timers for this feels like a bad practise, even though it would work.
So to make it more clear, the user suppose to engage in certain activity like walking for a few minutes. So I can't let the timer to stop when user is answering a call or opened a music app to switch music or something else. Timer still needs to run and I need to measure the number of steps and distance with geolocation. It need to work flawlessly even if user opened another app, forgot about my app, and it would still run for the remaining time, then made a record to the database and stopped.
Try the following code snippet,
works both on android and ios
import { DeviceEventEmitter, NativeAppEventEmitter, Platform } from 'react-native';
import _BackgroundTimer from 'react-native-background-timer';
const EventEmitter = Platform.select({
ios: () => NativeAppEventEmitter,
android: () => DeviceEventEmitter,
})();
class BackgroundTimer {
static setInterval(callback, delay) {
_BackgroundTimer.start();
this.backgroundListener = EventEmitter.addListener("backgroundTimer", () => {
this.backgroundTimer = _BackgroundTimer.setInterval(callback, delay);
});
return this.backgroundListener;
}
static clearInterval(timer) {
if (timer) timer.remove();
if (this.backgroundTimer)
_BackgroundTimer.clearInterval(this.backgroundTimer);
_BackgroundTimer.stop();
}
}
export default BackgroundTimer;
Usage
const timer = BackgroundTimer.setInterval(callback, 1000);
BackgroundTimer.clearInterval(timer)
For some reason I got the following error when using #Aravind Vemula's answer.
When calling BackgroundTimer.clearInterval(timer); the following error appears:
timer.remove is not a function
That's why I modified the code slightly.
// parameter removed
static clearInterval() {
// ADD this if statement
if (this.backgroundListener){
this.backgroundListener.remove();
}
if (this.backgroundTimer)
_BackgroundTimer.clearInterval(this.backgroundTimer);
_BackgroundTimer.stop();
}
The above code checks if a backgroundlistener is registered. If yes it removes all listeners and especially our backgroundTimer.
Usage:
BackgroundTimer.clearInterval(); // removed parameter
After my change, everything is working fine on iOS 14.3.
#Aravind Vemula's answer working properly. But if user open the app from the background and timer code is added in background handler then when you stop the timer it is not working. So following changes you need to make in both the methods.
static setInterval(callback, delay) {
if (!this.backgroundListener && !this.locationTimer) {
_BackgroundTimer.start();
this.backgroundListener = EventEmitter.addListener('backgroundTimer', () => {
this.locationTimer = _BackgroundTimer.setInterval(callback, delay);
});
return this.locationTimer;
}
}
static clearInterval() {
if (this.backgroundListener) {
this.backgroundListener.remove();
}
if (this.locationTimer) {
_BackgroundTimer.clearInterval(this.locationTimer);
}
this.backgroundListener = false;
this.locationTimer = false;
_BackgroundTimer.stop();
_BackgroundTimer.start();
}

Timer in react web app not working in mobile when browser closed

I'm working on a React based timer app. The countdown works perfectly both in web and mobile but it freezes/miscounts when on the browser in mobile, it is minimized or closed to background. Is there any way of getting the timer to run as expected in the background when browser minimized or phone locked?
timer = () => {
if (!this.props.paused) {
this.setState(
prevState => ({ time: prevState.time - 1 }),
() => {
if (this.state.time === 0) {
clearInterval(this.state.countdown);
this.props.onEnd();
}
}
);
}
};
This is my code for the timer function which decrements time and calls onEnd function when countdown over.
componentDidMount() {
const countdown = setInterval(this.timer, 1000);
}
This is called every 1 second by the setInterval function.
Is there an easy way of getting the timer to work as expected from background for mobiles? I've been recommended service workers. In a create-react-app setup what can be done to implement this functionality using service workers?

Firebase backed UI freezes during cronjob because of 1000 "on" events

I have ReactJs app with Firebase as database/backend.
There are 1000 items that are synced with firebase and i get new data with
firebase.database().ref().child('path').on('value', snapshot => {...})
while normal usage, users are changing data of that list, it all updates for all and all happy. ReactJs side is optimised well, it all works w/o lag.
Problem if when i run cronjob updating all those items with some 3rd party data and every user get's on event fired by firebase 1000 times at once one after the other. Browser freezes, RAM usage ~2-3GB (normal usage ~200mb).
There are 2 options what i'm thinking about, maybe you could add something:
Make cron update step-by-step update 1 item per second so fire all those 1000 on events during all 15 minutes timespan and just run cron forever, when it's done updating last item, just start again.
Make some abstraction layer for firebase connection and if on event is fired like 5 times /s disconnect with off and then after couple seconds re-connect with on so i would be disconnected during batch updates.
I like #2 more because then i can do whatever needed with cronjob and it also solves any possible future issues with batch updates.
It seems like your browser process is getting overloaded by the number of items that are queued up by the batch processing.
The best solution is probably to limit the amount of data that the browser process pulls in from Firebase to something it can handle:
firebase.database().ref().child('path')
.limitToFirst(10)
.on('child_added', snapshot => {...})
This way your browser will never see more than 10 items.
You'll note that I switched from a value event to child_added, which will probably also help. If you have a queue, you should probably also handle child_removed to remove the item from the browser UI. So you'll end up with something like:
var query = firebase.database().ref().child('path').limitToFirst(10)
query.on('child_added', snapshot => {
// add item to UI
})
query.on('child_removed', snapshot => {
// remove item from UI
})
I know, that for most cases it would be possible to limit results with limitToFirst() as Frank van Puffelen suggested, but problem is I need all data available in UI for all kind of selections, auto completions not talking about fast data filtering w/o extra call to server
Current solution:
I listen for all coming events from firebase if buffer overloads i just use goOffline and then re-connect after some time. Client don't see any difference, because goOffline lets fire local events normally and all UI works well read more here: https://firebase.google.com/docs/reference/js/firebase.database.Database#goOffline
I add event listener for each child in firebase, i'd like to have one global listener, but it doesn't work for me, there is connected question: How to listen for ALL firebase .on('value') events on root node?
let database = window.firebase.database();
// go offline if incomes more events per second from firebase
let events_buffer = 0;
let online = true;
const go_online = () => {
if (events_buffer > 6) {
setTimeout(() => {
go_online();
}, 3000);
} else {
online = true;
database.goOnline();
}
};
const handle_buffer = () => {
if (events_buffer > 6) {
if (online) {
online = false;
database.goOffline();
setTimeout(() => {
go_online();
}, 5000);
}
}
};
setInterval(() => {
events_buffer = events_buffer > 0 ? events_buffer - 1 : events_buffer;
}, 500);
// listen for all events. Connected: https://stackoverflow.com/questions/38368328/how-to-listen-for-all-firebase-onvalue-events-on-root-node
database.ref().child('clients').on('value', () => {
events_buffer++;
handle_buffer();
});
database.ref().child('users').on('value', () => {
events_buffer++;
handle_buffer();
});
//
// ... add listeners for all childs
//
export const firebase = window.firebase;
https://gist.github.com/liesislukas/0d78b6ac9613b70bafbb8e1601cc740e
for max buffer value i use 6 because on initial load app requires ~3-4. 6 can be reached on with some anomaly with my app.

Categories

Resources