I have been given some educational literature explaining asynchronous happenings in JS...
Take the following example where, server1 is a different server to the one running the website and the getData() function will execute a complex SQL query and then return a large dataset:
var data = server1.getData();
console.log(data);
We can be almost certain that the console will say
undefined
. This is because the 2nd line of code will be executed before the result of getData() is returned.
My understanding is that the 2nd line will only be executed when then function has returned and its return value is assigned to data
. If, indeed, getData() returns 'a large dataset', then by the time we get to the 2nd line data
will be, 'a large dataset'.
Can assignment be deferred like this? I'm very familiar with async calls to remote servers and handling them through callbacks. But I believe that a simple function call in JS will return once (at most) and code is essentially executed single-threaded and sequentially executed.
Is this documentation somewhat misleading in its attempts to explain the pitfalls of asynchronous programming, however well intentioned?
The documentation could be either misleading, or a deliberate attempt to pose a situation that won't work in order to explain why it won't work... which I would call misleading anyway.
JavaScript is single threaded - so any call out from the event queue must run to completion and return to the event queue (task manager) before another call out can begin.
var data = server1.getData();
console.log(data);
could return a large set of data, if and only if obtaining the data was requested as a synchronous operation, and further provided that the server "server1" allows cross origin requests (presuming "different server" means a different domain, protocol or port). Synchronous data requests are seriously discouraged as they stop the web page responding until the request is complete. If coded this way, the value of data
would only be undefined
it deliberately chosen as a value to indicate "no data available".
The await
operator introduced in ECMAScript 2017 can wait on a promise of an asynchronous result to become fulfilled, and delay assignment of the result to a variable. But usage such as
var data = await server1.getData();
console.log(data);`
has restrictions that prevent its use in the example: it can only be used inside an async
function, and async
functions return a Promise object. So even if the server1.getData
method were written as an async
function, and internally used await
to wait for data arrival, assign it to a variable and then return if from the function, the return value of an async
function is not returned to its caller but used to fullfill the promise it returned when the call was actually made.
server1.getData().then( data=>console.log(data)).catch(err=>console.error(err));
is how the asynchronous operation might be coded to work if getData
returns a promise. If called, call back functions provided by .then
and .catch
are called asynchronously, some time later. Meaning the code executing the above line can return to the event loop and let other things happen before the result of the query is sent back to the requesting web page.
As for
We can be almost certain that the console will say undefined.
using the provided code? No. More likely in code for current (ECMA script version 6 or later compliant) browsers, we can be almost certain the console will say Promise { <state>: "pending" }
or similar.