I'd like to be able to take a function that doesn't take a callback and determine if it will execute asynchronously.
In particular, I'm working with Node.js on the Intel Edison using mraa, and it has native C++ implemented functions like i2c.readReg(address) that doesn't accept a callback.
How can I determine if a function is blocking the processor for other system processes?
How can I determine if other JS can run in the interim?
Or am I not even approaching this the right way?
You can't really determine asynchronicity programmatically. It should be clear from the API presented because if it's asynchronous, then there pretty much have to be signs of that in the way you use it.
If a function is asynchronous, then that means that it does not directly return the result from the function call because the function returns before the result is ready. As such, the documentation for the function has to tell you how to obtain the result and if it's asynchronous there has to be another mechanism such as:
a callback function you can pass in
a returned promise
some sort of event listener on the object
some other notification mechanism
examine the code of the function
function naming convention (such as the suffix "Sync" that node.js uses)
If the function directly returns the result of the function call, then it is synchronous and other Javascript code will not run during that call.
If a function is not already asynchronous, the only way to turn that into an async operation is to run it in a different thread or process and marshall the value back to the main thread (calling some sort of callback in the main thread when the value is ready).
you can analyze js transformed into an abstract syntax tree with a tool like acorn. you could check to see if function arguments get executed. however, it would be difficult to tell if it was being executed as a callback or for some other purpose. you could also check to see if blocking functions were being called.
i'm not sure if this would get you all the way there but it would be a handy tool to have.
This is not exactly a solution, just a hint on cases which might be indeed a solution.
Many franeworks or libraries, define functions which can work either synchronously or asynchronously, depending on whether the last function argument (the callback) is given.
For example:
function dummy_sync_or_async(data, callback)
{
if (callback)
{
// call async code
//..
callback(result);
}
else
{
// call sync code
// ..
return result;
}
}
Then one can check the number of arguments received (for example if working as a proxy to these function methods) and check these against the function signature (i.e function.length)
Then one can decide whether the function is called in sync or async mode.
Related
Is there a way to tell if your function is being called synchronously or asynchronously?
For example, if I have a function shown below?
async function callMe() {
console.log("Am I called asynchronously?", callMe.isCalledAsync);
}
callMe(); // false
await callMe(); // true
The use case is I've needed to convert an existing function from sync to async and for testing purposes and because Chrome Debugger is reporting odd results, I want to check from inside the function that it's being called asynchronously. Another use case is if it's a public method than I want to make sure it's called using await.
Chrome Debugger seems to be aware of the await and async as shown in the screenshot below but either the debugger is incorrect or my code is incorrect or the JIT is not processing the calls async because Chrome Debugger is saying that only the first call is async but the recursive calls are not as shown in the image below.
We all know what you are supposed to do. But developers don't always do that; on purpose or on accident. And that's where dev tools like type checkers and autocomplete and intellisense and all development tools help assist and remind developers what's going on and what we might have missed. So having the feature doesn't preclude or prevent writing good code.
No, it's not possible for a function to determine if a caller used the await keyword. It's not even possible for a function to have knowledge from the runtime about whether or not a caller invoked it in an async context.
Because it's a public method I want to make sure it's called using await.
This is the responsibility of a compile-time lint rule, not of a function's runtime implementation. You (or the linter) will need to examine the source/AST of the calling code to make that determination.
I am a beginning javascript programmer. I have been trying to understand asynchronous javascript but I wanted to clear up a couple of things.
I understand that javascript runs in a single thread and that you can use callback functions to make your code asynchronous, but I am confused about what makes a callback function asynchronous or not.
A lot of the async callbacks seem to follow a pattern where a function has as its parameters a certain action and then a callback function which is to execute when that action is complete:
jQuery.get('page.html', function (data) {
console.log("second");
});
console.log('first');
What is it specifically that makes the callback in the parameter here execute at a later time? Is it that the get method here is pre-defined as some sort of a special method (because it fetches a file) that if you pass a function as a second parameter, it behaves in a asynchronous manner?
How can you make functions that you would write yourself asynchronous?
Thanks
It could be one of several things that makes asynchronous code asynchronous:
Timer Events (i.e. setTimeout() and setInterval(), which each accept callback functions as arguments that they execute at a later time)
DOM Events (i.e. attaching an event listener with a callback function to an HTML element or other DOM node, in which case your callback function is executed upon that event firing)
Other APIs provided by the browser (i.e. XMLHTTPRequest, which emits events based on things the browser does natively under the hood)
In Node.js or similar serverside environment, any I/O libraries that directly access resources such as disks or the network
Generally speaking, setTimeout() and setInterval() are the only vehicles for asynchronous execution in native JS (as opposed to the DOM, browser, or other APIs provided by the specific runtime)
In the case of your example, jQuery's .get() method is simply a wrapper for the browser's XMLHTTPRequest API, which creates a new XHR object that in turn emits events based on the status of the HTTP request, and attaches listeners with callbacks to those events.
I saw this post: https://www.codementor.io/nodejs/tutorial/manage-async-nodejs-callback-example-code, and after running the codes I confirm that nodejs is asynchronus.
However I created 2 js files to test asynchronus feature of nodejs again.
File 1: callback_example.js
exports.countless = function(callback){
var date = new Date();
console.log("*" + date.getSeconds());
var x = 0;
for(var i = 1; i <= 1000000000; i++){
x++;
}
callback(x);
date = new Date();
console.log("**" + date.getSeconds());
}
exports.check = function(callback){
var date = new Date();
console.log(date.getSeconds());
callback(123);
date = new Date();
console.log(date.getSeconds());
}
File 2: call.js
var call = require('./callback_example');
call.countless(function(x){
console.log(x);
});
call.check(function(x){
console.log(x);
});
And when I execute call.js in terminal as node call, I saw that after countless() finished, then check() run. It means that nodejs is synchronus? Why? Can anyone help me answer that? Thank you very much!
when u r calling call.countless() it is executing that function however there is nothing blocking I/O inside that. So Runtime is busy with doing for loop operation. If u had written any Blocking I/O operation then you would have seen the asynchronous nature of NODE JS.
e.g., Blocking I/O Operation: File Read/Write, TimeOut, DB Operation, Ajax call
After the for loop is complete then Interpreter goes to second function.
node.js uses the V8 Javascript engine and it executes lines of Javascript synchronous one after the other. If you write sequential coding statements such as in both your countless and check methods in your question, then those are executed synchronously just like in pretty much any other programming language.
Here's part of the node.js description from https://nodejs.org/en/.
Node.js uses an event-driven, non-blocking I/O model that makes it
lightweight and efficient.
This, I think, describes it better than just saying node.js is asynchronous as it described better what it actually does.
Only real asynchronous operations that make use of some outside interface such as networking are actually non-blocking in node.js. In that case, calling the non-blocking function starts the operation and then Javascript execution continues on the next lines of Javascript. When the non-blocking operation completes some time in the future, an event is inserted in the event queue and when the V8 engine has finished executing the current thread of execution, that event can be pulled from the event queue and a callback will get called.
You cannot write truly asynchronous operations from scratch (where actual code gets executed in the background) in pure Javascript. You need help from an external interface (such as networking, file I/O, etc...) in order create an actual async operation. You can simulate one with timers, but that isn't actually asynchronous because nothing actually executes in the background. Timers just shift the timing of when things run (they don't actually do work in parallel with your Javascript execution).
Here's an example of an asynchronous operation in node.js:
var fs = require('fs');
console.log("one");
fs.readFile('temp.txt', function(err, data) {
if (err) {
console.log(err);
} else {
console.log("got data");
}
});
console.log("two");
This will generate the following output:
one
two
got data
The fs.readFile() operation is actually asynchronous. After you call it, it does its work in the background while the rest of your Javascript in the statements that follow continue to execute. When it completes, sometime in the future, it will call it's callback with either an error or the data.
Node in itself is not asynchronous, it just uses an event loop as a primary construct. Iterations of the event loop are executed synchronously, just like any other programming language.
Your example here does not use asynchronous code at all. Just because something is inside of a callback doesn't necessarily mean it is asynchronous (otherwise map would be asynchronous, for example). You're simply employing higher-order functions here.
Try putting these both inside individual setTimeouts; the invocation order will not be guaranteed.
Node guarantees run-to-completion (that is, any function will be wholly executed unless it throws until the first return statement), so any synchronous code will be executed in the order it is written - just like any other imperative language. Any I/O operations or things like using a Promise will however have their callbacks added to a task queue to be executed at some point in the future, so their execution order is not guaranteed.
Note that NodeJS is single-threaded and large for loops will eat up that single thread as it is a CPU bound operation, so take care when doing computationally heavy stuff like that as you will hang your entire application. For computationally heavy stuff you could yield to using a child process written in another language better suited for such a thing (using the child_process module).
I'm learning node.js and I got most of the fundamentals down about asynchronous non-blocking I/O. My question is what's the point of creating a function with callbacks when the function itself isn't asynchronous. Even if the function you are creating has a call to an asynchronous function, I can't find a reason why you'd use a callback. I see this a lot in the node.js code i'm looking at.
For example, a function that sends an HTTP request and returns the parsed output of the request:
function withCallback(url, callback) {
request(url, function(err, response, html) {
if (err)
callback(err, null);
callback(null, JSON.parse(html));
});
}
function withoutCallback(url) {
request(url, function(err, response, html) {
if (err)
throw err;
return JSON.parse(html);
});
}
The first function with a callback returns the result through a callback while the second function just returns it normally.
Was going to write as a comment, but went a bit too long.
You are asking a couple of questions. To address the very correct point that the commenters make, the second example just won't work and as #Hawkings states more clearly, the result can't be captured (by your code). It won't work because the return in the second example the anonymous function you are creating (the actual callback being passed to request) is being invoked and returning its result deep within the request function. Also, in your example, control would have already returned to the caller of withoutCallback well before that return JSON.parse() line gets called, and as written, foo = withoutCallback(...) would result in foo being undefined.
If you look at the code for a library that uses callbacks you will see how these are invoked and it may make more sense why this isn't going to work. (Although I would suggest looking at a simpler library than request - if you are fairly new to node, I think you will find the request library to be a a bit confusing).
However, in the case of what you state your question is (which is not illustrated in your examples): "My question is what's the point of creating a function with callbacks when the function itself isn't asynchronous[?]"
There is not much point in that particular circumstance unless a) you want to future proof it in case it may become asynchronous because of added functionality or b) you want to have a common interface in which other implementations would be asynchronous. To use a browser example just because it comes readily to mind, if you were implementing a generic basic data storage solution, one implementation of which would use LocalStorage (synchronous) but others which might use IndexedDB, or a remote call (both asynchronous) - you would still want to write the LocalStorage implementation using callbacks so you could easily switch among the implementations.
If you don't like the callback style, consider learning to work with, and use libraries that make use of, other techniques or language features for handling asynchronicity, including Promises, Generators or in applicable cases, EventEmitters. I am personally a big fan of Promises. Having said that, I wouldn't suggest any of those until you get your head around the hows and whys of callbacks.
// synchronous Javascript
var result = db.get('select * from table1');
console.log('I am syncronous');
// asynchronous Javascript
db.get('select * from table1', function(result){
// do something with the result
});
console.log('I am asynchronous')
I know in synchronous code, console.log() executes after result is fetched from db, whereas in asynchronous code console.log() executes before the db.get() fetches the result.
Now my question is, how does the execution happen behind the scenes for asynchronous code and why is it non-blocking?
I have searched the Ecmascript 5 standard to understand how asynchronous code works but could not find the word asynchronous in the entire standard.
And from nodebeginner.org I also found out that we should not use a return statement as it blocks the event loop. But nodejs api and third party modules contain return statements everywhere. So when should a return statement be used and when shouldn't it?
Can somebody throw some light on this?
First of all, passing a function as a parameter is telling the function that you're calling that you would like it to call this function some time in the future. When exactly in the future it will get called depends upon the nature of what the function is doing.
If the function is doing some networking and the function is configured to be non-blocking or asychronous, then the function will execute, the networking operation will be started and the function you called will return right away and the rest of your inline javascript code after that function will execute. If you return a value from that function, it will return right away, long before the function you passed as a parameter has been called (the networking operation has not yet completed).
Meanwhile, the networking operation is going in the background. It's sending the request, listening for the response, then gathering the response. When the networking request has completed and the response has been collected, THEN and only then does the original function you called call the function you passed as a parameter. This may be only a few milliseconds later or it may be as long as minutes later - depending upon how long the networking operation took to complete.
What's important to understand is that in your example, the db.get() function call has long since completed and the code sequentially after it has also executed. What has not completed is the internal anonymous function that you passed as a parameter to that function. That's being held in a javascript function closure until later when the networking function finishes.
It's my opinion that one thing that confuses a lot of people is that the anonymous function is declared inside of your call to db.get and appears to be part of that and appears that when db.get() is done, this would be done too, but that is not the case. Perhaps that would look less like that if it was represented this way:
function getCompletionfunction(result) {
// do something with the result of db.get
}
// asynchronous Javascript
db.get('select * from table1', getCompletionFunction);
Then, maybe it would be more obvious that the db.get will return immediately and the getCompletionFunction will get called some time in the future. I'm not suggesting you write it this way, but just showing this form as a means of illustrating what is really happening.
Here's a sequence worth understanding:
console.log("a");
db.get('select * from table1', function(result){
console.log("b");
});
console.log("c");
What you would see in the debugger console is this:
a
c
b
"a" happens first. Then, db.get() starts its operation and then immediately returns. Thus, "c" happens next. Then, when the db.get() operation actually completes some time in the future, "b" happens.
For some reading on how async handling works in a browser, see How does JavaScript handle AJAX responses in the background?
jfriend00's answer explains asynchrony as it applies to most users quite well, but in your comment you seemed to want more details on the implementation:
[…] Can any body write some pseudo code, explaining the implementation part of the Ecmascript specification to achieve this kind of functionality? for better understanding the JS internals.
As you probably know, a function can stow away its argument into a global variable. Let's say we have a list of numbers and a function to add a number:
var numbers = [];
function addNumber(number) {
numbers.push(number);
}
If I add a few numbers, as long as I'm referring to the same numbers variable as before, I can access the numbers I added previously.
JavaScript implementations likely do something similar, except rather than stowing numbers away, they stow functions (specifically, callback functions) away.
The Event Loop
At the core of many applications is what's known as an event loop. It essentially looks like this:
loop forever:
get events, blocking if none exist
process events
Let's say you want to execute a database query like in your question:
db.get("select * from table", /* ... */);
In order to perform that database query, it will likely need to perform a network operation. Since network operations can take a significant amount of time, during which the processor is waiting, it makes sense to think that maybe we should, rather than waiting rather than doing some other work, just have it tell us when it's done so we can do other things in the mean time.
For simplicity's sake, I'll pretend that sending will never block/stall synchronously.
The functionality of get might look like this:
generate unique identifier for request
send off request (again, for simplicity, assuming this doesn't block)
stow away (identifier, callback) pair in a global dictionary/hash table variable
That's all get would do; it doesn't do any of the receiving bit, and it itself isn't responsible for calling your callback. That happens in the process events bit. The process events bit might look (partially) like this:
is the event a database response? if so:
parse the database response
look up the identifier in the response in the hash table to retrieve the callback
call the callback with the received response
Real Life
In real life, it's a little more complex, but the overall concept is not too different. If you want to send data, for example, you might have to wait until there's enough space in the operating system's outgoing network buffers before you can add your bit of data. When reading data, you might get it in multiple chunks. The process events bit probably isn't one big function, but itself just calling a bunch of callbacks (which then dispatch to more callbacks, and so on…)
While the implementation details between real life and our example are slightly different, the concept is the same: you kick off ‘doing something’, and a callback will be called through some mechanism or another when the work is done.