I am using Observable.interval to schedule code execuiton at specified times:
let obs = Observable.interval(50).subscribe(()=>{
console.log(this.currentFrame+" "+new Date().getTime());
this.currentFrame++
});
This is the output. As you can see, after 6 iterations I already have a 10ms drift. How can I use Observable.interval, but also specify that it needs to recalculate next iteration based on the current drift?
0 1513972329849
1 1513972329901
2 1513972329952
3 1513972330004
4 1513972330057
5 1513972330110
Until #cartant's fix gets repulled, you could use expand and create the behavior yourself. Assuming delay will always drift forward, try the following:
function correcting_interval(interval) {
const start_time = new Date().getTime();
return Observable.of(-1)
.expand(v => Observable.of(v + 1).delay(interval - (new Date().getTime() - start_time) % interval))
.skip(1);
}
Related
I found many examples of how to reset timer, but they usually concerned manual reset (e.g. on-click button event).
I need a logic that will automatically reset the value when the countdown ends.
Timer:
type seconds = number;
const getRemainingTime$ = (store: Store): Observable<seconds> => {
// calculate fullTime based on the TriggerDate extracted from the State
// ...
return fullTime$.pipe(
switchMap((fullTime: seconds) =>
timer(0, 1000).pipe(
map((tickCount: number) => fullTime - tickCount),
takeWhile((remainingTime: seconds) => remainingTime >= 0)
)
)
);
}
Trigger (wait for 0 value on timer)
getRemainingTime$(this.store).pipe(
skipWhile((remainingTime: seconds) => remainingTime > 0),
)
.subscribe(data => {
const newTriggerDate: Date = new Date(new Date().getTime() + 60 * 1000); // +60 seconds
this.store.dispatch([new SetTriggerDateAction({ newTriggerDate })]);
});
...and it doesn't work -
When the remaining time is zero, the trigger goes crazy and dispatch an infinite number of actions. What is wrong?
PS: When I manually dispatch SetTriggerDateAction (onClick button), the problem disappears.
It was enough to replace skipWhile to a filter.
skipWhile
All values are emitted if the condition in skipWhile is met at least once.
filter
Only those values specified in the condition are emitted.
I have an endless stream of events and I need to limit them to 5, keep the rest paused for 3 seconds
So need to make a delay after every 5 calls
from([ 1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27,28 ])
.pipe(
// To demonstrate 1 after 1 values stream we use concatMap
// we return new Observalbe via of operator
// we pipe the delay for each element based on the index value we passed
// in our concatMap
concatMap((x,i) => of(x).pipe(
delayWhen((x) => {
console.log("im index: " + i);
// Not the first element, and every 5th element
return i !== 0 && i % 5 === 0 ? timer(3000): timer(0)})
))
)
.subscribe(x => console.log(x))
// Output: 1,2,3,4,5 ...delay 3s.... 6,7,8,9,10 ...delay 3s...
You can see in this stackblitz I made.
const stream = range(0, 100) // create dataset
.pipe(
bufferCount(5), // slice data into chunks
concatMap( // get this chunk
(msg) => of(msg).pipe(
delay(3000) // and emit every three seconds
))
)
stream.subscribe(item => console.log(item));
I am in requirement for solution where I have one Admin posts application for an Android app. I have placed a delete button for post. The requirement is that delete button must be shown for 5 minutes from time of posting.
Here is the ngif condition which I have used..
*ngIf="((((post.CreatedDate | date:'dd/MM/yyyy') == (PresentDate | date:'dd/MM/yyyy')) && ((post.CreatedDate | date:'HH') == (post.CreatedDate | date:'HH')))&&((post.CreatedDate | date:'mm')< (time)))"
Code in TS page for present time + 5 minutes
const d: Date = new Date();
this.PresentDate = d;
var x = new Date();
d.getHours(); // => 9
d.getMinutes(); // => 30
this.time = d.getMinutes() +5;
this.hours = d.getHours();
Please help with the solution
Long expression in html is not good practice.
*ngIf="canDeletePost(post)"
canDeletePost(post) {
return Date.now() - post.CreatedDate.getTime() < 5 * 60 * 1000;
}
If CreatedDate is Js date. 5 * 60 * 1000 - 5 min in milliseconds. Actually, have a method in ngIf is not good practice also.
Anyway, you don't need date pipe. Pipes is used for changing view.
i have 2 time:
start time is 10.00 and end time is 12.00 .
So i want to make like this :
10.15 10.30 10.45 until 12.00.
The interval of this time is 12.
So how can i to make the interval of the time?
for($i=$time['from'];$i<$time['end'];$i=Carbon::createFromFormat('H:i', $i)->addMinutes(15))
{
$time_interval[$i]=Carbon::createFromFormat('H:i', $i)->toTimeString();
}
How to know if the time have passed the end time?
can i use like this $i<<times['end']
You could use php's range and array map functions:
$start = Carbon::createFromTime(10,0,0);
$range = array_map(function($i) {
return $start->addMinutes($i * 15);
}, range(1,8,1));
I have to make a random numer (1 and 2) in .lua, and change this value every 3 seconds.
I have a variable = randomMode, this randomMode have to change every 3 seconds (1 or 2)
You could try making a kind of timer that changes the value. For example the main program loop could to change the variable every 3 seconds by using time stamps.
If you cant use a good way to implement a timer, maybe just checking time stamps since last call is good enough. For example this function randomizes the number on each call to GetRandomMode if more than 3 seconds has passed:
local lastChange = os.time()
local mode = math.random(1, 2)
function GetRandomMode()
local now = os.time()
if os.difftime(now, lastChange) > 3 then
lastChange = now
mode = math.random(1, 2)
end
return mode
end