Are All Node "callback" Functions Potentially Asynchronous? - javascript

I'm a (relative) node newbie getting in the system, and all the enthusiasm in the community for "just write callbacks, everything's asynchronous and event driven, don't worry!" has left me a little confused as to the control flow within a single program (or in more node-ish terms, the control flow during the handling of a single request in a larger program)
If I have the following program running under node
var foo = function(){
console.log("Called Foo");
};
var bar = function(){
console.log("Called Bar");
};
var doTheThing = function(arg1, callback){
callback();
};
doTheThing(true, function() {
foo();
});
bar();
Is there any chance that foo will execute after bar? When I run the program via the command line locally, it's always
Called Foo
Called Bar
but I see so many warnings from well intended evangelists along the lines of don't assume your callback will be called when you think it will, that I'm unclear if they're just warning me about library implementation details, or if node.js does something weird/special when you use a function object as parameter.

No, there's no chance. Not for that code.
If you're writing your own functions, or if you have access to the code, you don't need to assume, you know whether everything's synchronous or otherwise, but if you don't have access to the code, or haven't yet read it, then no, you can't assume callbacks are going to be synchronous.
It's however bad practice to make assumptions like that for two reasons, first is that just because it's synchronous now doesn't mean somebody else, or forgetful future you can't change it later, and secondly, because if it's all synchronous, why are you/they using callbacks in the first place? The entire point of callbacks is to allow for the possibility of asynchronous calls. Using callbacks and then acting like they're always going to be synchronous, even if you know that's the case, makes your code confusing for anybody else coming in.

No
Your sample code is 100% synchronous, single-threaded, simple top-to-bottom. But that's because you don't do any I/O, don't have any real asynchronous calls, and don't use process.nextTick, setTimeout, or setInterval. To more realistically simulate async calls do something like:
function fakeAsync(name, callback) {
setTimeout(function () {
callback(null, name);
}, Math.random() * 5000);
}
function logIt(error, result) {
console.log(result);
}
fakeAsync('one', logIt);
fakeAsync('two', logIt);
fakeAsync('three', logIt);
Run that a few times and you'll see out-of-order results sometimes.

Is there any chance that foo will execute after bar?
In your current code, no. Although your doTheThing function has an asynchronous function signature (i.e. it takes a callback as the last argument, which to an outsider with no knowledge about the function's implementation would suggest that it's asynchronous), it's actually fully synchronous, and callback will be called without yielding to the runtime.
However
You really have no reason to give your doTheThing code an asynchronous signature, unless you're accommodating for introducing real async behavior into doTheThing at some point. And at that point, you have a problem, because the order in which foo and bar are called will flip.
In my opinion, there are only two good ways of writing code like you do: Either make it set in stone that doTheThing will be synchronous (most importantly: that it won't be dependent on I/O), which means that you can simply return from the function:
doTheThing = function(arg1){
return null
};
doTheThing()
foo()
bar()
or change the stub implementation of doTheThing directly to include a call to setImmediate, i.e.
var doTheThing = function(arg1, callback){
setImmediate(function() { callback(); );
};
Note that this can also be written as
var doTheThing = function(arg1, callback){
setImmediate(callback);
};
but that's just because at this moment, callback does not take any arguments. The first version is more close to what you had.
As soon as you do this, bar will always be called before foo, and it has now become safe to introduce async functionality into doTheThing.

Related

Javascript - Advantage of Callbacks

i have a little problem in understand of callbacks. I have read a lot in the last 2 days and what i have understand is the following (correct me, if i'm wrong):
JavaScript is a single thread language and you can program synchronous and asynchronous.
Synchronous means, each statement waits for the previous statement to finish before executing. That can lead into trouble, because if for instance a connection to a database needs a lot of time, the statements after the previous has to wait.
Finally that's very bad and that's why it's better to program asynchronous in Javascript, because Asynchronous code doesn't have to wait, the code can continue to run and the user don't have to wait.
To program asynchronous the Callbacks (functions of higher order) are needed.
Now i have try to program a little example by a lot of tutorials, etc.
function testCallback(a,callback){
console.log('1.function and given parameter: '+a);
callback(10);
}
testCallback(5 , function(x){
console.log("2.function and given parameter of 1. function: "+x);
});
Is that right? the output is:
1.function and given parameter: 5
2.function and given parameter of 1. function: 10
I do not understand, what the advantage is of this code, because i think that can still lead into trouble? If "console.log('1.function and....') has problems, the callback(10) function would even stop or not?
Thanks for any help!
JavaScript is a single thread language...
No, it isn't. The language says nothing about threading. Most environments give you a single thread per global environment, though (and on browsers you can create more, which interoperate through messaging). NodeJS provides just the one thread. Some environments (such as Rhino or Nashorn on the JDK) provide true multi-threading (and all the advantages and hassles that can involve).
Using a callback doesn't make code asynchronous. Your example, for instance, is not asynchronous. Consider:
function testCallback(a,callback){
console.log('1.function and given parameter: '+a);
callback(10);
}
console.log("Before the call");
testCallback(5 , function(x){
console.log("2.function and given parameter of 1. function: "+x);
});
console.log("After the call");
Note how we don't see After the call until after 2.function and given parameter of 1. function: 10. If the callback were asynchronous, we'd see it before:
function testCallback(a,callback){
console.log('1.function and given parameter: '+a);
setTimeout(function() { // Using setTimeout
callback(10); // to make this call
}, 0); // asynchronous
}
console.log("Before the call");
testCallback(5 , function(x){
console.log("2.function and given parameter of 1. function: "+x);
});
console.log("After the call");
Whether a callback is called synchronously or asynchronously depends entirely on what the function you're passing it to does. For instance, the callback used by Array#sort is called synchronously, but the callback used by setTimeout is called asynchronously.
For code to be asynchronous, it has to start an operation and then have that operation complete later, triggering a callback. setTimeout does that, as does ajax when used correctly, as do a wide range of other things.
Note that callbacks are currently how you handle asynchronous behavior (simple callbacks like the above, or promise callbacks), but the next specification (ES2017) will define built-in language semantics for dealing with asynchronousity without callbacks in the form of async and await. You can use that syntax today if you transpile with a tool like Babel.
In javascript callbacks can be synchronous or asynchronous. Synchronous callbacks can have a lot of benefits, but they don't do anything to stop your code blocking.
I think the best way to understand what asynchronous code is, and why it's beneficial, is to learn how Javascript actually evaluates your code. I recommend this video, which explains the process very clearly https://www.youtube.com/watch?v=8aGhZQkoFbQ
A JavaScript Callback Function is a function that is passed as a parameter to another JavaScript function. Callbacks can be synchronous or asynchronous. Simply passing a function as parameter will not change its current behavior.
It's behavior can be changed by the method which will execute it by calling it inside an event listener or setTimeout function etc. Basically event listener or setTimeout etc are handled by webapi in async fashion. If callback functions are inside these functions then these are moved to a queue by webapi when they are activated like button click(event listener) or time declared in setTimeout passed. They will move from queue to stack(if stack is empty) and run on stack finally.
The main advantage of using callback function can be seen from below code :-
var add = function(x,y) {
return x+y;
}
var multiply = function(x,y){
return x*y;
}
var calculate = function(x,y,callback){
return callback(x,y);
}
console.log(calculate(4,9,add));

Isn't it better to be async with Node

Here is my code
var x = 0
data.results[0].taxonomies.some(function(e){
if(taxo.indexOf(e.code)!=-1){ //if at least one code from the data base is in my list of codes
callback(validLic(data.results[0].taxonomies)) //return true after some other validations
return true
}else{
x++
return false
}
})
if(x==data.results[0].taxonomies.length){callback(false)}//if the entire array was processed, and I didn't find anything I was looking for, return false
I'd like someone to confirm that due the async nature of node, the last if statement is at some point, bound to fire off before I'm done processing the array.
How can I better manage this situation without the help of some sync or parallel library?
The reason I ask it that way is because I'm under the impression that if I can't write something to be completely async, then I'm not writing it efficiently, right?
EDIT:
Based on Luc Hendirks' logic, I have changed my code to this:
var flag = data.results[0].taxonomies.some(function(e){
if(taxo.indexOf(e.code)!=-1){ //if at least one code from the data base is in my list of codes
return true
}else{
return false
}
})
if(flag==true){
callback(validLic(data.results[0].taxonomies))
}else{
callback(false)
}
Because this follows the sync traits outlined below, I shouldn't have an issue with flag being undefined before the callback is called now right?
Javascript (and Node) are single threaded, meaning it has only 1 CPU available. If the functions you call only require CPU time, making it async is useless. If you need to call a function and the CPU has to wait (do nothing), then making it async is very useful. Because while it is waiting until the function is finished it can do something else.
A function that checks if a url is valid with a regular expression can be synchronous, as the CPU needs to do some calculations and you get the result. If the function actually does a GET request and checks the response code, the CPU has to wait until the response is received. In the meantime it could do something else, so this function should be made asynchronous.
The difference of a synchronous and asynchronous function is that a synchronous function returns a value:
function(a) { return a; }
and an asynchronous function returns the result using a callback function (this is an actual function that you put in as a function argument):
function(callback){
// Do something that takes time but not CPU, like an API call...
callback('Some result');
}
A synchronous function is called like this:
var a = something();
Asynchronous like this:
something(function(result){
console.log(result);
});
So to answer your question, if some() is an asynchronous function, then the last if statement can be executed before the some function is finished. Because: the CPU does not want to wait. It can do other stuff while waiting. That's the power of asynchronous programming. t
It is also important to know that "parallel" does not exist in Javascript/Node. There is only 'doing stuff instead of waiting', like executing multiple API calls at the same time. That is not parallel computing as in using multiple threads.
Here is some more info: What is the difference between synchronous and asynchronous programming (in node.js)

Mechanics behind Javascript callbacks being asynchronous

I'm having a bit of trouble understanding the mechanics of JS callbacks. I have a fair idea of how callbacks can be used in JS, but I do not understand how a callback is asynchronous.
For e.g., if my understanding is correct, a callback is of the nature:
db.query(param1, param2 , callback_fn1(){..} );
And the implementation of db.query() is along the lines of :
db.prototype.query = function(p1 , p2 , callback ){
//some code
callback();
}
How does the above implementation make db.query an asynchronous function? Does this not mean that a function called callback is passed to query and that function is called inside query? It looks like query is just another synchronous function. Could someone help me understand what I'm overlooking here? Thanks!
The code sample you've shown is actually still synchronous because is instructed to run immediately. An asynchronous callback is a callback that doesn't immediately need to be executed, so it doesn't block the event loop until you instruct it to run.
The most common way in Node.js to do this is with process.nextTick() which runs a specified function when the event loop call stack is empty. Here's an example:
var async = function(args, callback) {
// do some work
process.nextTick(function() {
callback(val);
});
};
Then we call the function like this:
async(args, function(val) {
console.log(val);
});
console.log('end');
In this example, the function async() and console.log('end') are added to the call stack. The call stack empties once both of those functions are run, and once it's empty, console.log(val) then runs.
If you're still confused, think of process.nextTick() as an optimized version of this code:
var fn = function() {};
setTimeout(fn, 0);
It basically means "run this function as soon as possible when you are not busy".
Edit: I just now realized the question is tagged with node.js. My answer is more about Javascript in the browser, #hexacyanide's answer is more about node.js. I guess knowing both doesn't hurt, though!
The way you posted it the code will indeed be blocking. For asynchronous behavior there are a few things you can utilize, such as
setTimeout and setInterval
Built-in, asynchronous methods such as from the FileReader API
Ajax requests
Web workers (see #html5rocks)
Your example code could be written as follows (fiddle):
function doStuff(callback) {
setTimeout(function () {
for (var i = 0; i < 1000; i++) {
// do some busy work
var x = Math.sqrt(i);
}
callback();
}, 0);
}
console.log('start');
doStuff(function () {
console.log('callback called');
});
console.log('after doStuff()');
The setTimeout call will allow the Javascript interpreter/compiler (however exactly they work these days) to run the function in a non-blocking matter which is why (most likely), you will see the output
start
after doStuff()
callback called
Note that asynchronousity is different from multi-threading. Javascript is still single-threaded (with the exception of web workers!).
A more in-depth explanation can be found for example here

Test Javascript Function's Blocking Behavior

In Javascript, I have two versions of a recursive function, one that runs synchronously and one that uses simple scheduling to run asynchronously. Given certain inputs, in both cases the function is expected to have an infinite execution path. I need to develop tests for these functions, specifically a test to check that the asynchronous version does not block the main thread.
I already have tests that check the output callback behavior of these functions in non-returning cases, I am only concerned about testing the blocking behavior. I can limit how long the function runs to some long but finite amount of time for testing purposes as well. I am currently using QUnit but can switch to another testing framework.
How can I test that a non-returning, asynchronous function does not block?
Edit, For Clarification
This would be a bare bones example of the function I am working with:
function a()
{
console.log("invoked");
setTimeout(a, 1000);
}
a();
I am intentionally misusing some threading terms in my description because I felt they most clearly expressed the problem. By not blocking the main thread, I mean that invoking the function does not prevent the scheduling and execution of other logic. I expect the function itself will be executed on the main thread but I consider the function running as long as it is scheduled for execution in the future.
Unit Test are based on single-responsability-principle and isolation (separate the subject under test from it's dependencies).
In this case, you expect your function to run asynchronously but this behaviour is not done by your function, is done by the "setTimeout" function, so I think you must isolate your function from "setTimeout" since it's a dependency you don't want to test, the browser guarantees you it will work.
Then, as we trust "setTimeout" will do the asyncrhonous logic, we can only test our function calls to "setTimeout" and we can do this replacing "window.setTimeout" with another function while we must always restore it after the test is complete.
function replaceSetTimeout() {
var originalSetTimeout = window.setTimeout;
var callCount = 0;
window.setTimeout = function() {
callCount++;
};
window.setTimeout.restore = function() {
window.setTimeout = originalSetTimeout;
};
window.setTimeout.getCallCount = function() {
return callCount;
};
}
replaceSetTimeout();
asyncFunction();
assert(setTimeout.getCallCount() === 1);
setTimeout.restore();
I recommend you to use sinon.js as it provides many tools like spies who are functions than will inform you about how many times and with what arguments where called.
var originalSetTimeout = window.setTimeout;
window.setTimeout = sinon.spy();
asyncFunction();
// check called only once
assert(setTimeout.calledOnce);
// check the first argument was asyncFunction
assert(setTimeout.calledWith(asyncFunction));
Sinon also provides fake timers who does the setTimeout substitution but with so much more features, like the .tick(x) method who will simulate "x" milliseconds but in this case I think it doesn't help you.
Update to answer question edit:
1 - Your function executes infinitely so you cannot test it without interrupting it's execution, so you must overwrite "setTimeout" somewhere.
2 - You want your function to execute recursively allowing other code to be executed between iterations? great! but understand than your function can not do this your function only can call setTimeout or setInterval and hope this function work as expected. You should test what your function does.
3 - You want to test from Javascript (a sandboxed environment) than another Javascript code uses and releases the only one execution thread (the same you are using to test). Do you really think this is an easy test?
4 - but the most important one - I don't like white box because it couples the test with the dependency, if you change your dependency or how it's called in the future you will have to change the test. This problem doesn't exist with DOM function, DOM functions will keep the same interface for years, and for now, you have no other way to do what you want than calling one of those two functions, so I don't think in this case "white box testing" is a bad idea.
I told you this because I had the same problem testing a Promise pattern implementation than had to be always asynchronous, even if the promise is already fulfilled, and I've tested it using test-engine asynchronous-test way (using callbacks and stuff) and it was a mess, test failing randomly, so much slow test execution. Then I asked a TDD expert how can test be so hard and he answered than I was not following Single Responsability Principle since I was trying to test my promise implementation AND the setTimeout behaviour.
If you think about it from a Behaviour Driven Testing perspective then 'Does my function block?' is not a useful question. It will definitely block, a better question might be 'does it return in no more than 50ms'.
You could do this with something like :
test( "speed test", function() {
var start = new Date();
a();
ok(new Date() - start < 50, "Passed!" );
});
The issue with this is that if someone does do something silly that makes your function block indefinitely the test won't fail, it will hang.
Because JavaScript is single threaded there is no way around this. If I come along and change your function to :
function a() {
while(true) {
console.log("invoked")
}
}
The test will hang.
You can make breaking things this way harder by refactoring things a little. There are 2 separate things being done. Your chunk of work and the scheduling. Separate these and you'll end up with something like the following functions :
function a() {
// doWork
var stopRunning = true;
return stopRunning;
}
function doAsync(workFunc, scheduleFunc, timeout) {
if (!workFunc()) {
scheduleFunc(doAsync, [workFunc, scheduleFunc, timeout], timeout);
}
}
function schedule(func, args, timeout) {
setTimeout(function() {func.apply(window, args);}, timeout);
}
Now you're free to test everything in isolation. You can supply a mock workFunc and scheduleFunc to a test for doAsync to verify it behaves as expected and you can test your function a() without worrying about how it is scheduled.
It's still possible for a dunce programmer to put an infinite loop into the function a(), but because they don't have to consider how to run further units of work it should be less likely.
To test or prove an infinitely executing execution path will never block is next to impossible, so you have to split your problem up into parts.
Your path is basically foo(foo(foo(foo(...etc...)))), nevermind that SetTimeout actually removes recursion. So all you have to do is test or prove that your foo does not block (I tell you now that testing will be "a bit" easier than proving, more below)
So, does function foo block?
Talking a bit maths, if you want to know whether f(f(...f(x)...)) always has a value, you actually only have to prove that f(x) always has a value for any x that f can return. It does not matter how many recursions you have, if you can make sure their return values are fine.
What that means for your foo is that you only have to prove that foo does not block for any possible input value. Keep in mind that in this case, all global variables and closures are input values too. This means you have to sanity-check every single value you are using on every call.
To test, of course you will have to replace SetTimeout, but that is trivial, and if you replace it with an empty function (function(){}) it is easy to prove that this function does not block or otherwise alter your execution. You will then
Making things easier
Taking in what I wrote above, this also means that you would have to make sure no global function or variable that you are ever using will ever be changed to a point that your function breaks to a point it breaks. This actually is quite hard, but you can still make things easier for you by making sure you always use the same functions and values and that other functions can not touch them by using closures.
function foo(n, setTimeout)
{
var x = global_var;
// sanity check n here
function f()
{
setTimeout(f, n)
}
return f();
}
This way, you only have to test those values on the first execution. It's nice to be able to assume Math.Pi is actually Pi and not a string value containing "noodles". Really nice.
Do not use global mutable objects
Call those you can not circumvent using setTimeout to ensure they can not block
If you need return values, things will get really tricky, but possible, consider this:
function() {
var x = 0;
setTimeout(function(){x = insecure();}, 1);
}
All you have to do is
Use x next iteration
Sanity check value of x first!
Does SetTimeout block?
Of course this depends on whether setTimeout blocks. This is quite hard to prove, but a bit easier to test. You can't actually prove it since it's implementation is up to the interpreter.
Personally I would assume that setTimeout behaves like an empty function when it's return value is discarded.
Performing this asynchronous testing is actually possible in QUnit but is handled better in another JavaScript testing framework, Jasmine JS. I'll provide examples in both.
In QUnit you need to first call the stop() function to signal that the test is expected to run asynchronously, you should then call setTimeout with a function that includes your expectations as well as a call to the start() function to complete the block. Here's an example:
test( "a test", function() {
stop();
asyncOp();
setTimeout(function() {
equals( asyncOp.result, "someExpectedValue" );
start();
}, 150 );
});
Edit: Apparently there's also a whole asyncTest construct that you can use that simplifies this process. Take a look: http://api.qunitjs.com/asyncTest/
In Jasmine (http://pivotal.github.com/jasmine/), a Behavior Driven Development (BDD) testing framework, there are built-in methods for writing asynchronous tests. Here's an example of an asynchronous test in Jasmine:
describe('Some module', function() {
it('should run asynchronously', function() {
var isDone = false;
runs(function() {
// The first call to runs should trigger some async operation
// that has a side-effect that can be tested for. In this case,
// lets say that the doSomethingAsyncWithCallback function
// does something asynchronously and then calls the passed callback
doSomethingAsyncWithCallback(function() { isDone = true; });
});
waitsFor(function() {
// The call to waits for is a polling function that will get called
// periodically until either a condition is met (the function should return
// a boolean testing for this condition) or the timeout expires.
// The optional text is what error to display if the test fails.
return isDone === true;
}, "Should set isDone to true", 500);
runs(function() {
// The second call to runs should contain any assertions you need to make
// after the async call is complete.
expect(isDone).toBe(true);
});
});
});
Edit: Also, Jasmine has several built-in methods of faking out the setTimeout and setInterval functions of the browser without hosing any other tests in your suite that may depend on that. I would take a look at using those rather than manually overriding the setTimeout/setInterval functions.
Basically, JavaScript is single-threaded, so it will block the main thread. But :
I assume you're using setTimesout to schedule your function, so it won't be noticeable to the user if calls to that function don't take too much time (say, less than 200 or 300ms).
If you're doing DOM manipulation during that function (including Canvas or WebGL), then you're screwed. But if not, you can look into Web Workers, which can spawn separate threads that are guaranteed not to block the UI.
But anyway, JavaScript and the main loop, that's a tricky issue that's been bugging me a lot these past months, so you're not alone!
As soon as your function returns (after having set the timeout for it's next run), javascript will look at the next thing that requires running and run that.
As far as I can tell, the 'main thread' in javascript is just a loop that is responding to events (such as onload for a script tag, which runs the contents of that tag).
Based on the above two conditions, the calling thread is always going to run to completion despite any setTimeouts, and those timeouts will begin after the calling thread has nothing left to run.
The way I tested this was to run the following function right after the call to a()
function looper(name,duration) {
var start = (new Date()).getTime();
var elapsed = 0;
while (elapsed < duration) {
elapsed = (new Date()).getTime() - start;
console.log(name + ": " + elapsed);
}
}
Duration should be set to some period of time longer than the setTimeout duration in a(). The expected output would be the output of 'looper', followed by the output of repeated calls to a().
The next thing to test would be whether other script tags are able to run while a() and its child calls are executing.
You can do this like so:
<script>
a();
</script>
<script>
looper('delay',500); // ie; less than the 1000 timeout in a();
</script>
<script>
console.log('OK');
</script>
You would expect 'OK' to appear in the log despite the fact that a() and its children are still executing. You can also test variations of this, such as window.onload(), etc.
Finally, you'd want to ensure that other timer events work fine as well. Simply delaying 2 calls by half a second and checking that they interleave should show that works fine:
function b()
{
console.log("invoked b")
setTimeout(b, 1000);
}
a();
looper('wait',500);
b();
Should produce output like
invoked
invoked b
invoked
invoked b
invoked
invoked b
Hope that's what you were looking for!
EDIT in case you need some technical details on how to do it in Qunit:
If Qunit can't capture console.log output (i'm not sure), just push those strings into an array or a string and check that after it's run. You could override console.log in the test module() setup and restore it at teardown. I'm not sure how Qunit works but 'this' might have to be removed and globals used to store the old_console_log and test_output
// in the setup
this.old_console_log = console.log;
this.test_output = [];
var self = this;
console.log = function(text) { self.test_output.push(text); }
// in the teardown
console.log = this.old_console_log;
Finally, you can utilize stop() and start() so that Qunit knows to wait for all the events in the test to finish running.
stop();
kickoff_async_test();
setTimeout(function(){
// assertions
start();
},<expected duration of run>);
Based on all the answers, I came up with this solution that works for my case:
testAsync("Doesn't hang", function(){
expect(1);
var ranToLong = false;
var last = new Date();
var sched = setInterval(function(){
var now = new Date();
ranToLong = ranToLong || (now - last) >= 50;
last = now;
}, 0);
// In this case, asyncRecursiveFunction runs for a long time and
// returns a single value in callback
asyncRecursiveFunction(function callback(v){
clearInterval(sched);
var now = new Date();
ranToLong = ranToLong || (now - last) >= 50;
assert.equal(ranToLong, false);
start();
});
});
It tests that 'asyncRecursiveFunction' does not hang while processing by looking at the time between another scheduled function calls.
This is really ugly and not be applicable to every case but it seems to work for me because I can restrict my function to some large set of async recursive calls so it runs for a long but not infinite time. As I mentioned in the question, I am happy proving that such cases do not block.
BTW, the actual code in question is found in gen.js. The main problem was an async reduce generator. It correctly returned a value asynchronously, but in previous versions would stall because of synchronous internal implementation.

Is that asynchronous of any javascript calling?

I am quiet new to javascript, can not understand that why all javascript calls are asynchronous,
for example, we have calling with order like
call_function1;
call_function2:
if function2 is depend on the results of function1, that can not be ensured, because the execution is asynchronous. Is that true ? And why ?
If true, how to ensure they are synchronous.
If this is duplicated question, I am sorry, because it is quiet new for me.
Thanks fo your answer first.
JavaScript calls are synchonous. If second function depends on results of first function, you might use callbacks model.
function foo(callback) {
var results = // get some results;
callback(results);
}
function boo(results) {
// do something with results here..
}
foo(boo);
No Javascript has functions that guarantee order and behave much like other languages. For example:
function f1() {
alert(1);
}
function f2() {
alert(2);
}
f1();
f2();
You will always get 1 and then 2. What's more is AFAIK javascript runs on one thread so you don't have to worry about race conditions either.
The asynchronous part of javascript comes from waiting on events. For example if you make 2 ajax requests (the a in ajax standing for asynchronous is a hint), you cannot guarantee which will come back first and thus if you have different callbacks for the two requests, you can't guarantee which will be called first.
Calling two functions in a row is definitely not asynchronous.
In fact.. javascript is 100% synchronous. Unless you use 'web workers' all javascript will always run in a single thread, in a single process. There is never, ever a situation where 2 scripts are running at the same time.
Even if you handle an event, coming from an XMLHTTPRequest for instance, the event will only be triggered after all other javascript code has stopped executing.
As mentioned in the comments to your question, JavaScript function calls are usually not asynchronous. The following will be executed in order:
function sayHello() {
console.log("Hi");
}
function sayBye() {
console.log("Bye");
}
sayHello();
sayBye();
The above code will first print "Hi", then "Bye", as the calls to sayHello and sayBye are in that order.
However, if a function does perform some action asynchronously, and you have another function that relies on the result of that, you can supply the second function as a callback to the asynchronous request. For example:
xmlHttpRequestObj.onreadystatechange = function() {
if(xmlHttpRequestObj.readyState == 4 && xmlHttpRequestObj.status == 200) {
//Asynchronous call returned successfully. Do something that relies on that here.
}
}
I don't know how you say that "Javascript is generally said to be asynchronous". It is generally the opposite: Javascript is almost always not asynchronous.
So generally (no ajax, no callback, no event handling), the following functions calls will execute sequentially.
function1();
function2();
If you are assigning both these functions to a single event, both will be called concurrently, but will not be executed in parallel. Same if both are called at the same time (using setTimeout), or as an Ajax callback. See Is JavaScript guaranteed to be single-threaded? for a very good explanation.
You could have heard that Ajax is asynchronous. That is true when you consider the request to servers without interfering with the user, "in the background". But this does not mean that Javascript is asynch. In fact even with Ajax calls, the javascript part is single threaded.

Categories

Resources