Please explain example in nextTick documentation - javascript

Update: This turned out to be a really stupid question. I just failed to notice some simple things in the quoted example.
I've been looking at information about ticks and the event loop, and mostly it's clear, but there is an example in the nextTick documentation that puzzles me. It says:
It is very important for APIs to be either 100% synchronous or 100%
asynchronous. Consider this example:
// WARNING! DO NOT USE! BAD UNSAFE HAZARD!
function maybeSync(arg, cb) {
if (arg) {
cb();
return;
}
fs.stat('file', cb);
}
This API is hazardous. If you do this:
maybeSync(true, function() {
foo();
});
bar();
then it's not clear whether foo() or bar() will be called first.
First questions: why is foo not guaranteed to be called first? There is a simple function call (of maybeSync), an if, and a callback of cb=foo. I take it that something in this chain is in some way (possibly) asynchronous, pushing something to the event queue and continuing execution? I don't see how anything there could have that effect.
Second question: is there some documentation somewhere that could have helped me understand this on my own?

This is pretty straightforward. foo is guaranteed to be called first if there's no arg as well as foo is guaranteed to be called "last" if there is an arg. Just imagine call stacks here:
arg exists
maybeSync calls cb immediately within same event loop iteration. foo is called synchronously as well within same event-loop iteration
maybeSync returns - so fs.stat is never called in this case
bar is called after foo is done
arg does not exist
maybeSync calls fs.stat (which is asynchronous) providing cb as a callback
there's no more synchronous code to run within current event-loop iteration thus bar is called
fs.stat is complete and it calls cb on the next event loop iteration (after bar). foo executes synchronously, but within another event loop iteration this time
Both are quite obvious. The problem here is that in most cases you don't know in advance if there's any arg value (otherwise there's no need in if :)) so you could have two scenarios of running this code which makes things pretty complicated.
process.nextTick mimics async nature of fs.stat here, so that foo is always called on the next event loop iteration making the flow predictable.

Related

Javascript: setTimeout beahavior in this example [duplicate]

Simply put...
why does
setTimeout('playNote('+currentaudio.id+', '+noteTime+')', delay);
work perfectly, calling the function after the the specified delay, but
setTimeout(playNote(currentaudio.id,noteTime), delay);
calls the function playNote all at the same time?
(these setTimeout()s are in a for loop)
or, if my explanation is too hard to read, what is the difference between the two functions?
The first form that you list works, since it will evaluate a string at the end of delay. Using eval() is generally not a good idea, so you should avoid this.
The second method doesn't work, since you immediately execute a function object with the function call operator (). What ends up happening is that playNote is executed immediately if you use the form playNote(...), so nothing will happen at the end of the delay.
Instead, you have to pass an anonymous function to setTimeout, so the correct form is:
setTimeout(function() { playNote(currentaudio.id,noteTime) }, delay);
Note that you are passing setTimeout an entire function expression, so it will hold on to the anonymous function and only execute it at the end of the delay.
You can also pass setTimeout a reference, since a reference isn't executed immediately, but then you can't pass arguments:
setTimeout(playNote, delay);
Note:
For repeated events you can use setInterval() and you can set setInterval() to a variable and use the variable to stop the interval with clearInterval().
You say you use setTimeout() in a for loop. In many situations, it is better to use setTimeout() in a recursive function. This is because in a for loop, the variables used in the setTimeout() will not be the variables as they were when setTimeout() began, but the variables as they are after the delay when the function is fired.
Just use a recursive function to sidestep this entire problem.
Using recursion to deal with variable delay times:
// Set original delay
var delay = 500;
// Call the function for the first time, to begin the recursion.
playNote(xxx, yyy);
// The recursive function
function playNote(theId, theTime)
{
// Do whatever has to be done
// ...
// Have the function call itself again after a delay, if necessary
// you can modify the arguments that you use here. As an
// example I add 20 to theTime each time. You can also modify
// the delay. I add 1/2 a second to the delay each time as an example.
// You can use a condition to continue or stop the recursion
delay += 500;
if (condition)
{ setTimeout(function() { playNote(theID, theTime + 20) }, delay); }
}
Try this.
setTimeout(function() { playNote(currentaudio.id,noteTime) }, delay);
Don't use string-timeouts. It's effective an eval, which is a Bad Thing. It works because it's converting currentaudio.id and noteTime to the string representations of themselves and hiding it in the code. This only works as long as those values have toString()s that generate JavaScript literal syntax that will recreate the value, which is true for Number but not for much else.
setTimeout(playNote(currentaudio.id, noteTime), delay);
that's a function call. playNote is called immediately and the returned result of the function (probably undefined) is passed to setTimeout(), not what you want.
As other answers mention, you can use an inline function expression with a closure to reference currentaudio and noteTime:
setTimeout(function() {
playNote(currentaudio.id, noteTime);
}, delay);
However, if you're in a loop and currentaudio or noteTime is different each time around the loop, you've got the Closure Loop Problem: the same variable will be referenced in every timeout, so when they're called you'll get the same value each time, the value that was left in the variable when the loop finished earlier.
You can work around this with another closure, taking a copy of the variable's value for each iteration of the loop:
setTimeout(function() {
return function(currentaudio, noteTime) {
playNote(currentaudio.id, noteTime);
};
}(currentaudio, noteTime), delay);
but this is getting a bit ugly now. Better is Function#bind, which will partially-apply a function for you:
setTimeout(playNote.bind(window, currentaudio.id, noteTime), delay);
(window is for setting the value of this inside the function, which is a feature of bind() you don't need here.)
However this is an ECMAScript Fifth Edition feature which not all browsers support yet. So if you want to use it you have to first hack in support, eg.:
// Make ECMA262-5 Function#bind work on older browsers
//
if (!('bind' in Function.prototype)) {
Function.prototype.bind= function(owner) {
var that= this;
if (arguments.length<=1) {
return function() {
return that.apply(owner, arguments);
};
} else {
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner, arguments.length===0? args : args.concat(Array.prototype.slice.call(arguments)));
};
}
};
}
I literally created an account on this site to comment on Peter Ajtai's answer (currently highest voted), only to discover that you require 50 rep (whatever that is) to comment, so I'll do it as an answer since it's probably worth pointing out a couple things.
In his answer, he states the following:
You can also pass setTimeout a reference, since a reference isn't executed immediately, but then you can't pass arguments:
setTimeout(playNote, delay);
This isn't true. After giving setTimeout a function reference and delay amount, any additional arguments are parsed as arguments for the referenced function. The below would be better than wrapping a function call in a function.
setTimeout(playNote, delay, currentaudio.id, noteTime)
Always consult the docs.
That said, as Peter points out, a recursive function would be a good idea if you want to vary the delay between each playNote(), or consider using setInterval() if you want there to be the same delay between each playNote().
Also worth noting that if you want to parse the i of your for loop into a setTimeout(), you need to wrap it in a function, as detailed here.
It may help to understand when javascript executes code, and when it waits to execute something:
let foo2 = function foo(bar=baz()){ console.log(bar); return bar()}
The first thing javascript executes is the function constructor, and creates a function object. You can use either the function keyword syntax or the => syntax, and you get similar (but not identical) results.
The function just created is then assigned to the variable foo2
At this point nothing else has been run: no other functions called (neither baz nor bar, no values looked up, etc. However, the syntax has been checked inside the function.
If you were to pass foo or foo2 to setTimeout then after the timeout, it would call the function, the same as if you did foo(). (notice that no args are passed to foo. This is because setTimeout doesn't by default pass arguments, although it can, but those arguments get evaluated before the timeout expires, not when it expires.)
After foo is called, default arguments are evaluated. Since we called foo without passing arguments, the default for bar is evaluated. (This would not have happened if we passed an argument)
While evaluating the default argument for bar, first javascript looks for a variable named baz. If it finds one, it then tries to call it as a function. If that works, it saves the return value to bar.
Now the main body of the function is evaluated:
Javascript looks up the variable bar and then calls console.log with the result. This does not call bar. However, if it was instead called as bar(), then bar would run first, and then the return value of bar() would be passed to console.log instead. Notice that javascript gets the values of the arguments to a function it is calling before it calls the function, and even before it looks up the function to see if it exists and is indeed a function.
Javascript again looks up bar, and then it tries to call it as a function. If that works, the value is returned as the result of foo()
So, function bodies and default arguments are not called immediately, but everything else is. Similarly, if you do a function call (i.e. ()), then that function is executed immediately as well. However, you aren't required to call a function. Leaving off the parentheses will allow you to pass that function around and call it later. The downside of that, though, is that you can't specify the arguments you want the function to be called with. Also, javascript does everything inside the function parentheses before it calls the function or looks up the variable the function is stored in.
Because the second one you're telling it to call the playNote function first and then pass the return value from it to setTimeout.

Want to understand need of callback functions in javascript

I am new in learning JavaScript. I read about callback functions but I am unable to understand its real use.
So, please help by any real world example.
Below is small code depicting use of callback function in but that too is not clear to me.
var friends = ["Mike", "Stacy", "Andy", "Rick"];
​
friends.forEach(function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick​
});
The uses of JavaScript callback functions are many. You probably already know that it's simply a function that we pass as an argument to another function. This means that we can have a function called foo. Lets says foo is some sort of method that runs an array through a sort, however the actual sorting function is variable. So we could use foo for every algorithm, by simply passing values like so.
foo([1,6,1,2], quickSort);
Assuming we have a quickSort method.
Generally speaking, callbacks are however used to call something AFTER a function has executed. So why not just call one function after the other, you say?
foo();
bar();
Why would you pass bar to foo ? Well, usually callbacks are used when dealing with asynchronicity. So, the bar function would get called way before, say an AJAX request gets a response, or before a setTimeout triggers it's callback.
As for the specific example you provided, it's simply a simplified way to iterate over an array. With the added benefit that you can use a named function, so you can declare it earlier and separate your code better.
Javascript is generally synchronous, i.e. commands are executed one after the other.
However there are times where you want a function to be asynchronous, so you call a function and don't want to wait for it to complete before you move on to your next task.
Callbacks are used by asynchronous functions. When the function completes, the callback function is run, without the rest of the code having to wait for it.
var friends = ["Mike", "Stacy", "Andy", "Rick"]; friends.forEach(function (element, index, array) { console.log((index+1) + "." + element ); });
The concept of Callbacks in JavaScript is that you can assign functions to variables.
Everthing, in JavaScript, except for simple types as string and number, are objects (and even those have functions to be called as they were objects as well).
Let's take your function for instance, as example:
Syntax
arr.forEach(callback[, thisArg])
Parameters
callback
Function to execute for each element, taking three arguments:
currentValue
The current element being processed in the array.
index
The index of the current element being processed in the array.
array
The array that forEach is being applied to.
thisArg
Optional. Value to use as this when executing callback.
It takes a callback function that will be called for each element.
Also, we have the definitions of asynchronous calls in JS (with a help of timeouts/interval and AJAX calls).
The idea of the callback functions doesn't stays just in JS. Anywhere it would be easier or just simples, to use a function passed as reference we have the concept of callback (it just goes insane with this feature of AJAX in js, that why it's so common to say JS is asynchronous).
You could read a litte more about it here:
http://www.sitepoint.com/javascript-goes-asynchronous-awesome/
In JavaScript, function below is an object:
function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick​
}
Let call this object A.
When you pass the code friends.forEach(A), browser will understand that when running through the array friends it will trigger A.
So at the end, callback function is just like you "define" function but you will use it later on.

If a callback calls the enclosing function, would it be called a recursive call?

For example:
If http.request call is made in res.on('end') callback, then is the call recursive?
http.request(options, function(res) {
res.on('data', function(chunk) {
data+=chunk;
});
res.on('end', function(){
//do some stuff
http.request(options, function(res) {...});//is this recursive?
});
}).end();
Edit:
Let's take a simpler example: suppose there is a function which reads a file character by character:
var noOfChar = 10;
var i = 0;
readChar(function processChar(char){
if(i < noOfChar) {
console.log(char);
i++;
readChar(processChar); //is this recursive?
}
}
Rather than arguing about what to label it, let's consider some concrete attributes of your code, and how it is similar or different to what people usually mean by "recursive".
Usually a recursive function is something that grows the stack at each step (except for tail-call recursion, which uses a trick to prevent that growth). But in node, an asynchronous callback discards the stack of the outside context. (Try raising an exception inside the callback and see for yourself.) So this code does not grow the stack.
Also usually a recursive function is something that calls itself, but I don't see that happening anywhere in your example. The two listeners on http are different functions.
The second example doesn't call itself directly, but it does call itself indirectly. You have a "base case" (noOfChar >= 10) at which point the recursion unwinds. If readChar were synchronous you'd even be growing the stack. So this seems closer to recursive.
Notice that in your second example you have a named function, whereas the first example has only anonymous functions. In general I don't think recursion is possible without a named function (or at least some variable that holds the function), because otherwise how can a function refer to itself?
I don't think it'll be recursive if you are going to pass a different callback to it.
If you will pass same callback to both, it is going to be recursive.
Recursive means if I'm calling the same function in function definition itself. But if you are going to pass different callbacks it will be something like bellow.
Suppose you have 2 different callbacks callback1 and callback2.
You have passed first callback to outer http.request and second callback to inner http.request, so outer http.request will be executing the code given in callback1 but the inner will be executing code given in callback2.
I don't understand the meaning of the question.
Will you be flogged to death by your boss if the answer is yes?
Is there a law against recursivity?
http.request is only a means to an end. One way or another, you will need to call it more than once to process a transaction.
The trouble with your example code is that you handle an asynchronous exchange in one big lump of code, which handles the response directly without tracking the state of the transaction.
The only comment that comes to my mind is that this kind of logic is extremely fragile, because the termination conditions are dependent on whatever parameters are passed to your requests, leaving the door open to a score of potential problems like out of sync answers and infinite loops (whether they deserve the name of "recursive calls" is of little interest if they hang the system in the end).
I would rather advise to build an explicit state machine to track the progress of intended HTTP exchanges, which would dispense of philosophical questions about recursivity and the associated "good practices".
I'm going to try to answer my own question because I think now I understand Recursion a bit better. Maybe this will help someone else.
My doubt was if a function invokes a callback, which calls the function again would it be called recursion. I feel it is similar to indirect recursion where function1 calls function2 and function2 calls function1 again. So it doesn't matter if function1 calls function2 which calls function3 which in turn call function1 again, it is still recursive. In the same way it shouldn't matter if function invokes a callback which invokes another callback which calls the function. If second example is recursive, first can also be recursive.
Recursive solution to a problem has to do more with how the problem is solved than the language implementation like growth of stack. Take tail-recursion for consideration, it doesn't increase call stack, yet no ones questions about it's recursiveness.
So the key point is to think recursively. Take the whole problem, if a part of it can be solved in the same way as the original problem then the solution is Recursive. A function calling itself may not qualify for being recursive. Some may call it self referencing functions but not recursive.
Recursion should at least consist of a base case and a recursive case, each self-reference should bring the input value closer to the base case which would end the recursion.So I think both of the examples mentioned in the question are not recursive.
Recursive calls may not result in increase in call stack. There is tail call recursion which keeps call stack size constant.
Take the following examples which consist of callbacks, here outer function stack frame may or may not be in memory.
var input = [[1,2,3],[4,5,6],[7,8,9]];
function double(ip) {
return ip.map(function (element) {
if(Array.isArray(element)) {
return double(element);
}
else {
return 2 * element;
}
});
}
console.log(double(input));
I would call it as recursive. Also we can do Anonymous Recursion, so explicitly naming a function isn't necessary.

Javascript stack and recursive calls

Assume the following method(Just curious, I'm hopefully fail in js)
foo(0);
function foo(i){
if(i<1000){
setTimeout(function(){foo(i+1);}, 1000);
}
alert('I am foo');
}
So if I got it true, it should alerts around 1000 I am foos after 1000 seconds.
So doesn't it bother the browser about keeping the is in a sort of big stack? it should be too much I think or I'm wrong?
Yes, you will alert 1000 "foo" messages with this code.
However, the browser will not get bothered by the amount of i variables. i is a local variable to foo and as a result, it is only kept around as long as foo is executing. Each time the setTimeout callback is finished executing, i and the entire function's footprint is eligible for garbage collection by the browser (which will happen at an opportune time).
The reason for this is that there is no preserved memory call stack here because of the use of setTimeout. setTimeout does not do anything with a returned value from foo and as a result there are no pointers in memory keeping that function nor its variable environment from being collected.
Your call stack will look like this as your code goes through it's loop:
main() [local foo]
main() -> foo [local i = 0]
main()
(empty)
setTimeout()
setTimeout() -> foo [local i = 1]
setTimeout()
(empty)
setTimeout()
setTimeout() -> foo [local i = 2]
setTimeout()
(empty)
over and over until i equals 1000.
It happens this way because setTimeout is a browser api that waits n amount of time and then inserts the callback into the callback queue. The callback will then get picked up by the event loop and executed when the callstack is empty.
So, no, you aren't in any danger of overloading the browser with stacks or vars or whatever you were worried about. Your callstack will remain small because each time foo is executed, it fires off a setTimeout and returns. the i will stay in memory until the setTimeout's callback gets executed, at which point a new i will be created within the scope created by executing foo. That new i will stay in memory until the next setTimeout executes, on and on.
Here's a video that may help explain how this works. http://www.youtube.com/watch?v=8aGhZQkoFbQ
Firstly in javascript there is no "int" you have to say var i. And it gets alone the type for the declaration. If you want get Information about stack. You can use the debug console. And navigate to the call stacks. Its a nice feature you have also a nice overview. I prefer the Chromes Debugger. You can get there with pressing F12
1000 is in a stack is not a really big size for a browser to deal with.
Moreover, there won't be more than 2 is at the same time (maybe even only one), with each function executing every second.
This code won't load 1000 calls to get triggered with an interval of 1 second, this will chain calls, preventing the stack to get bloated.

Alternative approach to force sequential javascript execution

I am looking for a way to execute multiple functions in JavaScript and force them to run sequentially. The most straight forward way to achieve this is to use callback functions (which has been the most commonly found suggestion on this forum and elsewhere). The problem with callback functions is that the resulting code can easily become hard to read as the result may be a lot of nested callback functions.
Am wondering if the following code will execute sequentially as well:
function doSomeThingOne(){
//do something intense here that takes quite some processor time
void(0); //dummy statement for illustration purposes only
return true;
}
function doSomeThingTwo(){
//do something intense here that takes quite some processor time
void(0); //dummy statement for illustration purposes only
return true;
}
function testSequentialExecution(){
//a temporary variable just to capture the
var bolTemp=false;
//execute the first function
bolTemp=doSomeThingOne();
//after this is done, execute the second function
bolTemp=doSomeThingTwo();
}
//kick off the (hopefully) sequential execution
testSequentialExecution();
Am looking for a plain JavaScript solution.
If my functions doSomeThingOne() and doSomeThingTwo() do not execute code that runs a-synchronically (like a typical AJAX request) will this coding-style force the functions to execute synchronically?
Yes, of course. That works just the same way JavaScript doesn't shuffle the content of any other function - expressions in a function will always be executed in order. Specifically, all expressions inside of a code block (something between {}) will always be executed in order. A function body is such a code block.
The expression might have async side effects (like calling setTimeout() or making AJAX calls) but the expression itself is evaluated in order. The browser can just determine to keep references to part of the expression and execute those parts later.
Your question seems like you spent too much time in the async world ;-)
The main problem is usually that you do something async. And then, the function ends and eventually, the callback will be called. There is no good way to serialize this. Maybe JavaScript promises will help.

Categories

Resources