Redux dispatch on requestAnimationFrame taking 250-300ms - reactjs

I'm having a hard time figuring out why this is the case, but one of the simplest actions in my React app is being dispatched on each animation frame like so:
step = () => {
if (this.player.howler.playing()) {
this.props.playProgress(this.player.seek())
window.requestAnimationFrame(this.step)
}
}
playProgress is an absurdly simple action, but is taking a ludicrous amount of time to execute:
/**
* Dispatched when currentlyPlaying's position changes
*
* #param {integer} pos Position to progress to (in seconds)
*
* #return {object} An action object with a type of PLAY_PROGRESS
*/
export function playProgress(pos) {
return {
type: PLAY_PROGRESS,
pos,
}
}
And it's reduced like so:
case PLAY_PROGRESS:
return state
.setIn(['currentlyPlaying', 'pos'], action.pos)
Why on earth would that take so long to execute?? window.requestAnimationFrame only gives you 16ms before it executes again, so 250ms isn't cutting it... Any help is appreciated!

This is an old question, but I believe it was related to an infinite scrolling issue we encountered in Chrome. Here's a rundown: github.com/CassetteRocks/react-infinite-scroller/pull/125

Related

How to document useCallback with jsdoc?

If I have my arrow function, wrapped in a React useCallback, how am I supposed to document it with JSDoc?
const floopPig = useCallback((pigKey, floopCost) => {
const pigAbility = pigs[pigKey];
if (pigAbility.floopCost < magicPoints) {
return pigAbility.activate()
} else {
throw new Error('Not enough magic points');
}
}, [pigs, magicPoints])
I have been trying this in VSCode, but I haven't gotten anything to show up on hover over:
/**
* Floops a pig
* #callback
* #param {number} pigKey unique key for each pig
* #param {number} floopCost how much the ability costs to activate
*/
I think I've followed the documentation for #callback correctly. But based on this answer perhaps I'm using #callback for the wrong purpose?
How am I supposed to document this?
I've had success documenting the callback function itself.
const getNewToken = useCallback(
/**
* Requests a token, either by the normal flow or with a refresh token
* #param {URLSearchParams} axiosBody The body of the axios request
*/
async (axiosBody) => {
//Function
}, [myVar]);
Lower in the code, I can see intellisense working its magic when I call my function. I'm not 100% sure this is the best answer, but this is the best answer I've found

how can i throttle an array into a stream created using rxjs "from" operator?

I want to throttle the contents of an array observable created with "from" operator to display each value 1 second apart. Omitting the throttle displays 1 to 10 as expected. If I introduce a throttle into the observable's pipe() the stream only outputs "1".
https://stackblitz.com/edit/rxjs-behaviorsubject-simpleexample-knappa?file=index.ts
// RxJS v6+
import { from, interval } from 'rxjs';
import { throttle } from 'rxjs/operators';
const observable = from([1,2,3,4,5,6,7,8,9,10]);
const example = observable.pipe(
// removing this line displays the full array all at once
throttle(ev => interval(1000))
// what we want is 1..2..3..4.. printed in succession, 1 number a second
);
example.subscribe(x => console.log(x));
How can i print the numbers of the array 1 second apart?
By extension how can i add numbers to the stream created using "from" and continue to throttle those values 1 second apart?
This is quite unintuitive. Any help will be massively appreciated. Thanks in advance.
I had to google but this should give you what you want:
// RxJS v6+
import { of, from } from 'rxjs';
import { delay, concatMap } from 'rxjs/operators';
const observable = from([1,2,3,4,5,6,7,8,9,10]);
const example = observable.pipe(
// removing this line displays the full array all at once
concatMap(item => of(item).pipe(delay(1000)))
// what we want is 1..2..3..4.. printed in succession, 1 number a second
);
example.subscribe(x => console.log(x));
https://stackblitz.com/edit/rxjs-delay-from-array

Rx Swift simple timer not working

I have this RxSwift code in swift 3
let bag:DisposeBag = DisposeBag()
var sig:Observable<Int>!
sig = Observable<Int>.interval(1.0, scheduler: MainScheduler.instance)
sig.subscribe(onNext: { (milsec) in
print("Mil: \(milsec)")
}).addDisposableTo(bag)
i run this code when button tapped, but its not print anything on console.
DisposeBag will dispose of your subscription once it goes out of scope. In this instance, it'll be right after the call to subscribe, and it explains why you don't see anything printed to the console.
Move the definition of dispose bag to the class creating the subscription and everything should work fine.
class MyViewController: UIViewController {
let bag:DisposeBag = DisposeBag()
dynamic func onButtonTapped() {
var sig:Observable<Int>!
sig = Observable<Int>.interval(1.0, scheduler: MainScheduler.instance)
sig.subscribe(onNext: { (sec) in
print("Sec: \(sec)")
}).addDisposableTo(bag)
}
}
On a side note, interval expects an interval in seconds, so it will only tick every seconds as oposed to milliseconds.

Cleanup .throttle()'d callbacks in componentWillUnmount

I have the following setup:
componentDidMount() {
Dispatcher.on('app:update', _.throttle(this.postLoad, 1000));
}
componentWillUnmount() {
Dispatcher.removeListener('app:update', this.postLoad)
}
However, I'm receiving errors in the console in regards to trying to call setState on a Component that isn't mounted (happens inside postLoad). What are my best options to cancel the throttled functions in the componentWillUnmount?
.throttle is from Lodash.
You're likely seeing your throttled function being called on the trailing edge of the timeout. To illustrate, let's look at the default behavior of throttle():
var throttled = _.throttle(function() {
console.log('ran');
}, 1000);
for (var i = 0; i < 3; i ++) {
throttled();
}
// → ran
// → ran
This is strange, there's two calls made to throttled(). The loop actually makes three calls, but the expectation is that since it's been throttled to 1 second, there should only be one call.
By default, the trailing option for throttle() is set to true. This means that after the timeout has elapsed, the throttled function is called again - assuming it was called after the timeout starts and before it ends.
The simple solution in your case might be turning this option off, as follows:
var throttled = _.throttle(function() {
console.log('ran');
}, 1000, { trailing: false });

Create a simple countdown in processing

I have searched up so many sites on Google to try and get this to work but NO ONE seems to have this anywhere , and if they do it's just NOT working with my program... What I am trying to achieve is to have a player recoil that when the player gets hit, he has a "x" amount of time between getting hit the first time and the second time.
So I have a Boolean "hit" = false and when he gets hit, it changes to true. Which means he can't get hit again until it's changed to false again.
So I'm trying to set up a function in my program to set a "timer" for "x" amount of seconds IF hit = true and once that timer hits "x" amount of seconds, hit will get switched back to false.
Anyone have any ideas?
Thanks!!
A simple option is to manually keep track of time using millis().
You would use two variables:
one to store elapsed time
one to store the wait/delay time you need
In the draw() method you would check if the difference between the current time (in millis.) and the previously stored time is greater(or equal) to the delay.
If so, this would be your cue to do whatever based on the delay chosen and update the stored time:
int time;
int wait = 1000;
void setup(){
time = millis();//store the current time
}
void draw(){
//check the difference between now and the previously stored time is greater than the wait interval
if(millis() - time >= wait){
println("tick");//if it is, do something
time = millis();//also update the stored time
}
}
Here's a slight variation the updates a 'needle' on screen:
int time;
int wait = 1000;
boolean tick;
void setup(){
time = millis();//store the current time
smooth();
strokeWeight(3);
}
void draw(){
//check the difference between now and the previously stored time is greater than the wait interval
if(millis() - time >= wait){
tick = !tick;//if it is, do something
time = millis();//also update the stored time
}
//draw a visual cue
background(255);
line(50,10,tick ? 10 : 90,90);
}
Depending on your setup/needs, you may choose to wrap something like this into a class that can be reused. This is a basic approach and should work with the Android and JavaScript versions as well (although in javascript you've got setInterval()).
If you're interested in using Java's utilities, as FrankieTheKneeMan suggested, there is a TimerTask class available and I'm sure there are plenty of resources/examples out there.
You can run a demo bellow:
var time;
var wait = 1000;
var tick = false;
function setup(){
time = millis();//store the current time
smooth();
strokeWeight(3);
}
function draw(){
//check the difference between now and the previously stored time is greater than the wait interval
if(millis() - time >= wait){
tick = !tick;//if it is, do something
time = millis();//also update the stored time
}
//draw a visual cue
background(255);
line(50,10,tick ? 10 : 90,90);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.4/p5.min.js"></script>

Resources