Time is a Hidden Variable in JavaScript

John Lindquist
InstructorJohn Lindquist
Share this video with your friends

Social Share Links

Send Tweet
Published 4 years ago
Updated 3 years ago

Time causes bugs. This is because we often don't know how to handle the many different scenarios that emerge when dealing with asynchronous code. A main goal of this course is to help your feel comfortable attacking bugs due to time so you can build the advanced features that main your app shine.

Instructor: [0:00] When working with callbacks, time is always the hidden variable, meaning that if my broadcaster had a setTimeout and in the setTimeout, after one second it called this listener, and I hit Save here, you'll now see 2, 5 and then after one second, 6. That was this number, then plus this number, then plus this number after a delay of one second.

[0:27] Similarly, if inside of my broadcaster down here, I created a setTimeout, and I do this from the value*1000 to make it a second, and then I'll call the listener with the value, you'll now see one, and then two, and then three.

[0:52] You could even make it more complicated by still using the currentValue where you do currentValue again is += value, then passing that into here, currentValue and currentValue. Hitting save. Now you see 6, and 6, and 6.

[1:17] That's because this line had been run three times because these were invoked immediately, and currentValue value was trapped inside of this function as a closure and was updated before this function was called.

[1:30] These are all valid scenarios where your broadcaster could be timeouts, intervals, button clicks, input events, WebSockets, anything that takes a callback and pushes values into it.

[1:44] Then your operators, the key is giving them a good name, whether it's delay, buffer, state, or something that tries to describe what's going on inside. Code is never great at expressing the future. It is great to be able to capture functions that define the future inside of operators, where you could have this function capture this logic.

[2:04] If I duplicate this, change this to timeoutByValue, and set it back to what we had before, where these are the values, then I have the option of swapping out this operator for timeoutByValue, which is an operator, and getting 1, 2, and 3, or I could swap out my original operator, and now get 6, 6, and 6.

[2:37] Throughout the course, we'll be writing a lot of operators which will be able to capture asynchronous behaviors. We'll do our best to define the future in individual functions using closures and using callbacks.

~ 3 years ago

Hey there!

I feel like a missed a lesson between video 5 and 6.. I am not familiar with operators, and it is not clear that the operator is being called on the first run.

Defining a function that takes a function, and returns a function that takes a function is a bit rough without explanation haha.

Would it not be possible to pass these two functions as parameters to operator?

Ex: const operator = (broadcaster, listener) => ...

I am guessing it has something to with the scope/closure.

Thanks !

Richard Dyce
Richard Dyce
~ 3 years ago

That's my feeling too. The explanations for broadcaster and listener were clear, but there was a whiff of handwaving for the operator - it did feel if 30 seconds was missing between 5 and 6

~ 3 years ago

It became clear in the following section :)
Just a bit unnerving to start us off.

Chad
Chad
~ 3 years ago

I spent hours trying to fully understand this and my notes are below. I hope they help...

/* https://stackoverflow.com/questions/42893344/how-to-understand-chain-multiple-in-javascript?noredirect=1&lq=1 It's a higher-order function in that it returns another function. This is actually pretty easy to read once you're used to this notation. When you see multiple =>s, read each of them but the last one as return a function. Whatever is on the left-hand side of the =>, can be closure'd so to say in the returned function. The last => is the actual action you want to perform. */ // 1. A function is assigned to timeoutByValue (the first arrow function). // 2. A function is returned. That function creates a closure over broadcaster. // 3. That returned function is executed with listener as an argument. // 4. Consider it rewritten as: // >> const fn2 = timeoutByValue(broadcaster) // >> fn2(listener) let timeoutByValue = (broadcaster) => (listener) => { // 5. This block represents the execution of the second arrow function. // 6. Here, broadcaster() will be executed with an anonymous arrow function (using value for return). // 7. The broadcaster function will "callback" 3 times thru the anonymous arrow function (aka value). // 8. Each callback creates a 1 second timeout, and each is a closure over value. broadcaster((value) => { //-- callback goes here... setTimeout(() => { listener(value) }, value * 1000) }) } console.log("RUNNING: timeoutByValue") timeoutByValue(broadcaster)(listener)

//-- The equivalent, but with separate assignment/execution -- //console.log("RUNNING: timeoutByValue Equivalent") //const fn2 = timeoutByValue(broadcaster) // fn2 now contains a function that closes over broadcaster //fn2(listener) // fn2 is executed with the callback

//-- Written as functions (this might help) -- const timeoutByValue2 = function (broadcaster) { return function (listener) { broadcaster((value) => { setTimeout(() => { listener(value) }, value * 1000) }) } } //console.log("RUNNING: timeoutByValue2") //timeoutByValue2(broadcaster)(listener)

Chad
Chad
~ 3 years ago

Here is a gist for my previous comment...

https://gist.github.com/chadrey/c1f27ef4b62e4e2fa967e3c6a62c86a7

Markdown supported.
Become a member to join the discussionEnroll Today