How do I build a Clock using setInterval and clearInterval? - javascript

I am trying to Write a SecondClock class, with two methods: start and reset.​
In the start invocation, the callback gets invoked every second on the "seconds hand" of the clock. Always start with 1 and don't utilize the seconds value of the current computer clock time.
The first "tick" with value 1 occurs 1 second after the initial "secondClock" invocation.
The second "tick" with value 2 occurs 2 seconds after the initial "secondClock" invocation.
and so on.
Upon reset invocation, completely stops the "clock".
Also resets the time back to the beginning.
​
class SecondClock {
constructor(cb) {
this.cb = cb;
this.IntervalId;
this.tick = 'tick';
}
start(tick){
this.IntervalId = setInterval(this.cb(tick),1000);
}
reset(){
clearInterval(this.IntervalId);
}
}
// Border Line
const clock = new SecondClock((val) => { console.log(val) });
console.log("Started Clock.");
clock.start();
setTimeout(() => {
clock.reset();
console.log("Stopped Clock after 6 seconds.");
}, 6000);
I am able to start the clock and this is what I see in the console:
'Started Clock.'
undefined
Type Error on line callback is not a function at blob: callback is not a function
Type Error on line callback is not a function at blob: callback is not a function
Type Error on line callback is not a function at blob: callback is not a function
Type Error on line callback is not a function at blob: callback is not a function
Type Error on line callback is not a function at blob: callback is not a function
Type Error on line callback is not a function at blob: callback is not a function
'Stopped Clock after 6 seconds.'
Which should Ideally be:
'Started Clock'
1
2
3
4
5
6
'Stopped Clock after 6 seconds.'
Is there any way I can leverage the Date() class to accomplish this?
After I invoke the setInterval via clock.start() statement, I am able to invoke clearInterval after 6 seconds.
I am assuming this.cb(this.tick) is able to fetch this.tick only once. But after this.cb(this.tick) is pushed into callback queue, the error is seen.
Printing 'tick' instead of numbers was my first milestone. Further, I plan to implement it with counter is what I assumed. But clearly, I found it hard to implement even with 'tick'.
Would prefer to not to change anything below the border line.

I think the pointer you need is that setInterval or setTimeout should take a function as a first argument.
setInterval( this.cb(x) , 1000 ) //unless this.cb returns a function this wont run
Option 1: create an anonymous function
var _helper = function(){
myLogic(10);
};
setInterval (_helper, 1000);//first argument is a function
Option 2: your cb can return a function
var cb = function(x){
return function(){
//logic or side-effect
};
};
setInterval (cb(10), 1000); //first argument is still a function
Option 3: Possibly by using promises/resolve

Related

Combination of rxjs and setTimeout creates unexpected runtime behaviour

I have some problems to understand the difference between the following two snippets.
const a = Observable.create(
o => {
setTimeout(
()=>{
console.log("now 3");
o.next(3);
setTimeout(()=>{ console.log("and now 5"); o.next(5)}, 1500);}
, 1500);
}
);
const a2 = Observable.create(
o => {
setTimeout(
()=>{
console.log("here is 4");
o.next(4);
setTimeout(o.next(6), 1500);}
, 1500);
}
);
https://stackblitz.com/edit/rxjs-byqgnh?devtoolsheight=60
I removed in the second block only the console log.
The first block works like expected: first number is emitted after timeout, second number too.
The second block emitts both numbers simultanious. Can anybody explain the difference?
When you do
setTimeout(()=>{ console.log("and now 5"); o.next(5)}, 1500);
you are passing ()=>{ console.log("and now 5"); o.next(5)} as a callback function to setTimeout API, which will be probably trigger after 1.5sec. And Its fine since this is what you wanted to happen.
But when you do
setTimeout(o.next(6), 1500)
You are executing o.next(6) and emitting value right before you are passing it as a callback function to setTimeout, but when you see It's not a function signature, what o.next(6) generates is a undefined value which will be pass as a callback and chances you will get Callback must be a function error.
So, if you want o.next(6) to be passed as a callback function to setTimeout and emit value after 1.5 sec then you can pass it as
setTimeout(() => o.next(6), 1500)
or as
setTimeout(function(){
o.next(6);
}, 1500)
setTimeout takes a callback
The following with generate a runtime error
setTimeout(o.next(6), 1500);
TypeError [ERR_INVALID_CALLBACK]: Callback must be a function.
as the return type of n.next is undefined. Observables, however, catch errors and emit them as error events for you. So you don't see that in your example.
To fix this, you could give setTimeout a callback function instead.
setTimeout(() => o.next(6), 1500);

executing a block of code at a certain exact time in javascript

I want to execute a block of code (which includes recursive setTimeout) at a certain exact time in javascript.By writing get_current function i get the current time and with setInterval method with 1 mili second interval i compare the current time( fetched from get_current function) with my desired time and if that condition satisfies i execute a block of code recursively. i test my code with console messages and i understand that only once this code is executed and if statement is checked only once.
could any one help me doing that???
var dateString;
var delay=1500;
function get_current() {
var mydate = new Date();
var mili_real = mydate.getMilliseconds();
var hour_real=mydate.getHours();
var minute_real=mydate.getMinutes();
var second_real=mydate.getSeconds();
if(minute_real<10)minute_real="0"+minute_real;
if(hour_real==0)hour_real="12";
if(second_real<10) second_real="0"+second_real;
if(mili_real<10)mili_real="00"+mili_real;
else if(mili_real<100) mili_real="0"+mili_real;
dateString=hour_real+""+minute_real+""+second_real+""+mili_real;
}
setInterval(checkStart(),1);
function checkStart() {
get_current();
if (dateString == 145412578) {
var timerId = setTimeout(
function request() {
console.log("request"+delay);
if(delay<1600){
delay++;
} else {
delay--;
}
timerId=setTimeout(request,dealy);
}, delay);
} else {
console.log("waiting to start");
}
}
First, let's take a look at the docs: It says that setInterval takes two main parameters. There are optionally additional parameters to pass to the function when it's called, but let's ignore those and focus on the first two parameters. The second parameter is the time in milliseconds, which is clear for you. The first parameter is a function. Let's see your call
setInterval(checkStart(),1);
You pass checkStart() as your first parameter. It's a function call. There is no return in that function, which means that it "returns" undefined. So, your code above is functionally equivalent with the following:
checkStart();
setInterval(undefined,1);
So, the solution should be to pass the function instead its result to setInterval:
setInterval(checkStart,1);
and as a result, checkStart should be regularly called.

Output of one sample program of javascript is giving wrong answer

I was reading one book named 'Hands on node.js' by 'Pedro Teixiera'.
I was trying to execute one same program giving in that book that will call a function and that function is calling the same function recursively within some interval again and again.
But when I executed, it gives only one time '1' and stops
Please help me to figure it out why it is not able to call the same function again.
Sample program is as follows:
var schedule = function(timeout, callbackfunction) {
return {
start: function() {
setTimeout(callbackfunction, timeout)
}
};
};
(function()
{
var timeout = 10000; // 1 second
var count = 0;
schedule(timeout, function doStuff() {
console.log(++ count);
schedule(timeout, doStuff);
}).start(timeout);
})();
You aren't actually calling the function again. start() is the part that starts the timer.
schedule( timeout, function doStuff() {
console.log( ++count );
schedule( timeout, doStuff ).start(); // <--- added .start() here
}).start();
(Also note that the start() function doesn't take parameters.)
with some interval again and again
No, for that you would have used setInterval instead of setTimeout.
it gives only one time '1' and stops
Yes, your doStuff function doesn't put a new timeout. Your odd schedule function needs to be .start()ed!

JavaScript self invoking function

I'm trying to understand this example code, what is the function of line 15, why start(timeout)? (Sorry, I'm new to programming)
var schedule = function (timeout, callbackfunction) {
return {
start: function () {
setTimeout(callbackfunction, timeout)
}
};
};
(function () {
var timeout = 1000; // 1 second
var count = 0;
schedule(timeout, function doStuff() {
console.log(++count);
schedule(timeout, doStuff);
}).start(timeout);
})();
// "timeout" and "count" variables
// do not exist in this scope.
...why start(timeout)?
In that example, there's actually no reason for passing timeout into start, since start doesn't accept or use any arguments. The call may as well be .start().
What's happening is that schedule returns an object the schedule function creates, and one of the properties on that object is called start, which is a function. When start is called, it sets up a timed callback via setTimeout using the original timeout passed into schedule and the callback function passed into schedule.
The code calling schedule turns around and immediately calls the start function on the object it creates.
In the comments, Pointy points out (well, he would, wouldn't he?) that the callback function is calling schedule but not doing anything with the returned object, which is pointless — schedule doesn't do anything other than create and return the object, so not using the returned object makes the call pointless.
Here's the code with those two issues addressed:
var schedule = function (timeout, callbackfunction) {
return {
start: function () {
setTimeout(callbackfunction, timeout)
}
};
};
(function () {
var timeout = 1000; // 1 second
var count = 0;
schedule(timeout, function doStuff() {
console.log(++count);
schedule(timeout, doStuff).start(); // <== Change here
}).start(); // <== And here
})();
It's not very good code, though, frankly, even with the fixes. There's no particularly good reason for creating a new object every time, and frankly if the book is meant to be teaching, this example could be a lot clearer. Inline named function expressions and calls to methods on objects returned by a function...absolutely fine, but not for teaching. Still, I don't know the context, so those comments come with a grain of salt.
Here's a reworked version of using the schedule function by reusing the object it returns, and being clear about what bit is happening when:
(function () {
var timeout = 1000; // 1 second
var count = 0;
// Create the schedule object
var scheduleObject = schedule(timeout, doStuff);
// Set up the first timed callback
scheduleObject.start();
// This is called by each timed callback
function doStuff() {
// Show the count
console.log(++count);
// Set up the next timed callback
scheduleObject.start();
}
})();
The function schedule is executed as a function. That function returns an object. Like you can see with the { start... }. With the returned object it calls out the start function. This is called chaining. So the start function is executed after is set the function.
What is strange is that the timeout is passed to the start function which has no parameters.

Javascript: Could not really understand the function return

It is maybe incredibly easy but I couldn't solve what was going on.
function doSomething(a)
{
var num=10;
return setTimeout(
function(){ a(num); }, 1000);
}
The only thing that actually confuses me is the a(num) part. What actually it does?Reminder: I really am asking because I'm not familiar with the javascript syntax.
When the function doSomething() is executed it is passed the parameter a,
a is also some function that is then called when setTimeout() expires after 1 second,
then calling the function a() passing the argument called num
Example usage:
// call doSomething() passing the test() function as an argument
doSomething(test);
// takes a number as an argument and shows an alert with that value
function test(number)
{
alert(number);
}
// takes a function as an argument that will perform a 1 second timeout then execute the function called a
function doSomething(a)
{
var num=10;
return setTimeout(
function(){ a(num); }, 1000);
}
It calls the function referenced by the variable a, using the value referenced by the variable num as an argument.
setTimeout returns a timeoutID which can be used to cancel it using clearTimeout, so if you run doSomething a lot of times you will get different integer numbers which represent different timeoutID.
In your case a must be a function so you can call it using the parameter num
Example:
function doSomethingElse (justANumber) {
return justANumber + 1;
}
// Here you call your function
doSomething(doSomethingElse);
// or another special case
doSomething(function (justANumber) {return justANumber + 1;});

Categories