I have a function that has integration with my database, but before that I have a function which does some checks:
function checkVars (a, b){
if (a.a1 !== b.b1){
b.b1 = a.a1;
}
// and other 4 vars
}
After this I have a function to insert data into my database.
How can I be sure that my code is going to execute the comparative function before the database function?
I am using a callback, but is that possible without callbacks?
How can i be sure that my code is going to execute the comparative function before ?
Assuming you have:
checkVars(something, somethingElse);
doDatabaseWork();
...you know checkVars will be called and will run to completion before doDatabaseWork is called. Since checkVars does all of its work synchronously (it doesn't start any asynchronous processes), the fact it runs to completion before doDatabaseWork is called means all of its work is done before doDatabaseWork. It's only if checkVars starts an asynchronous process that you need to allow for that process not being complete yet when checkVars returns (and handle it via callbacks, direct ones or via promises). But what you've described doesn't start an asynchronous process in checkVars, so there's nothing to allow for.
Related
I want to preface by saying I've viewed a lot of stackoverflow questions regarding this topic, but I haven't found any 'duplicates' per se since none of them contain solutions that would solve this specific case.
I've mainly looked at How do I return the response from an asynchronous call?, and the section on 'Promises with async/await' would work inside an asynchronous function, but the function I'm working on is not async and is part of an existing codebase that I can't change easily. I wouldn't be able to change the function to async.
The section on callbacks wouldn't work either, which is explained further below. Anyway, I'll jump into my question:
I'm editing a function (standard function, not async) in JavaScript by adding an asynchronous function call. I want to wait until the async call finishes before I return from the function (since the result of the async call needs to be included in the return value). How would I do so?
I looked into using callbacks, which would allow me to write code which is guaranteed to run only after the async call completes. However, this wouldn't interrupt the flow of the program in the original function, and the original function could still return before the callback is run. A callback would allow me to execute something sequentially after the async function, but it wouldn't allow me to wait for asynchronous call to complete at the highest level.
Example code, which wouldn't return the desired result:
function getPlayers() {
... other code ...
let outfieldPlayers = asyncGetOutfieldPlayersCall()
... other code ...
allPlayers.add(outfieldPlayers)
return allPlayers // the returned value may or may not include outfield players
}
The actual problem I'm facing is a little more complicated - I'm calling the async function in each iteration of a for loop, and need to wait until all calls have completed before returning. But, I think if I can solve this simpler problem, I can solve the problem with a for loop.
Sadly, it is pretty much impossible to wait for async code in a synchronous way. This is because there is no threading in JS (most JS runtimes, but some are). So code is either synchronous or asynchronous.
Asynchronous code is possible because of the event loop. The event loop is part of the javascript runtime. It works by keeping a stack of callback functions that run when events trigger them - usually either timeout events (which you can set with setTimeout()) or IO events (which happen when you make disk or HTTP requests, or on user interaction). However, these callbacks only run when no other code is running, so only when the program is idle and all functions have returned.
This means that techniques like "spin loops" (where you just run a loop until a condition is changed by another thread) that work in threaded environments don't work because the async code won't run until the spin loop finishes.
More Info: https://medium.com/front-end-weekly/javascript-event-loop-explained-4cd26af121d4
If you are using NodeJS, this is possible through execSync.
This requires you to place your asynchronous code in a separate file, spawn a separate process using execSync, which will wait until it exits.
For example, consider the following async function which prints an array.
// task.js
(async function() {
await new Promise((resolve) => setTimeout(() => {
console.log(JSON.stringify([3,4,5]));
resolve();
}, 1000));
})();
Now, you can invoke this from your main process:
function asyncGetOutfieldPlayersCall() {
const execSync = require('child_process').execSync;
return JSON.parse(execSync("node task.js"));
}
function getPlayers() {
let allPlayers = [1,2];
// ... other code ...
let outfieldPlayers = asyncGetOutfieldPlayersCall();
// ... other code ...
allPlayers = allPlayers.concat(outfieldPlayers)
return allPlayers;
}
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));
I know JavaScript is synchronous by nature. So that when I call a function with web API It performs synchronously:
setTimeout(function(){
console.log('1');
}, 2000);
console.log('2');
it will print '2' then '1'.
But when I run a loop like for loop and increase the iteration it executes synchronously:
var first = function(){
for(var i=0;i<=100000000;i++){
if(i==100000000){
console.log('first')
};
};
};
var second = function() {
console.log('second')
};
var a = function() {
first();
second();
}
a();
It will print the first second respectively.
So, is JavaScript performing synchronously with native code?
The first example is asynchronous because you've explicitly asked it to be asynchronous by using setTimeout. setTimeout (and its relation setInterval) explicitly set up an asynchronous timed callback to the function you pass them.
The remaining examples don't use anything that creates asynchronousness like setTimeout (and ajax and such) do, so naturally it's synchronous.
I know javaScript is asynchronous by nature
No, JavaScript (the language) is synchronous by nature. Literally the only asynchronous aspect of JavaScript was added in ES2015 and relates to when the callback passed into a promise's then or catch is called. That's it. setTimeout, for instance, is not part of JavaScript; it's part of the host environment where JavaScript is largely used (browsers). (It's also part of a couple of non-browser host environments, like NodeJS.)
JavaScript is primarily used in an environment that encourages asynchronous operations (browsers) where it's used to respond to user events (asynchronous), ajax completions (asynchronous), and timer callbacks (asynchronous), but the language is almost entirely synchronous.
JS is event-driven, this is why you think its async.. But it only has async features..
for loop does not have any event-callbacks, so its just sync
I got to know that
JavaScript is sync and async functionality depends on your functions implementation.
It has an event loop and it executes synchronously but whenever it will get the async function( the function which takes callback i.e setTimeout ,fs.readFile() etc) which is not the part of the javaScript then,
It put the function into the queue and invoke the queue function after all the native code(which is in current scope) execute then it pop the queue and invoke the functions.
and setTimeout explicitly set up an asynchronously timed callback to the function.
check this javaScript Async behavior ;
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)
Promises in JS allow you to do async programming, as follows:
DoSomething().then(success, failure);
DoSomethingElse();
whenever i write the previous code it reaches DoSomethingElse() before it reaches success.
How is that possible? Isn't JS a single threaded environment (not including web-workers)? is it done with setTimeout?
Yes, JavaScript is single-threaded, which means you should never block this single thread. Any long-running, waiting operation (typically AJAX calls or sleeps/pauses) are implemented using callbacks.
Without looking at the implementation here is what happens:
DoSomething is called and it receives success and failure functions as arguments.
It does what it needs to do (probably initiating long-running AJAX call) and returns
DoSomethingElse() is called
...
Some time later AJAX response arrives. It calls previously defined success and failure function
See also (similar problems)
JavaScript equivalent of SwingUtilities.invokeLater()
Are there any atomic javascript operations to deal with Ajax's asynchronous nature?
jqGrid custom edit rule function using Ajax displays "Custom Function should return array!"
Promises in JavaScript usually involve some kind of call chains or fluent method call APIs, where function results usually provide continuation methods like with, then, when, whenAll etc plus some status flags that indicate if the result is in fact available. Functions with input parameters can also support promised values detecting that the input is a promise and encapsulation their functionality into a thunk that can be chained when the promised value is ready.
With these you can provide an environment where promises simulate a parallel language like this:
MyApi.LongRunningTask().then( function(result) { MyAppi.LongOtherTask(result); }).then
or a sequential use case where long running calls are not dependant:
var value1 = MyApi.LongRunningTask();
var value2 = MyApi.LongRunningOtherTask();
MyApi.DoSomeFunction( value1, value2).then ==> DoSomeFunction can check if values are ready and if not chains their then/when function to execute its logic.