So lets say you have this sync function you call a and another async function b that you want to put within a. And so you would have something like this:
async function b(){
//some code here
}
function a(){
}
And now lets say we add some code into a and call b:
async function b(){
//some code here
}
function a(){
b()
//other code here
}
Now lets say you want to run the code within a only if b has returned its promise. Well if you have direct access to b then its all fine, just make it a sync function. That would work but what if you didn't have access to b. Here comes the problem. If you specifically want to run it after b then you could use something like .then():
async function b(){
//some code here
}
function a(){
b().then(<results for example>=>{
//other code
})
}
But what if a was an async function, how would that work? Could i use await or anything of that sort?
You have to make a function async and await for b function, then b function will return data, otherwise it will return promise.
async function b(){
//some code here
}
async function a(){
const data = await b();
// Do something with data
}
Related
Let's say that:
a() {
console.log("i am a")
}
b() {
c() {
//call function a here
}
}
How do I call function a from function c?
functions declared like you are declaring them are hoisted to the top of the scope. a is available globally and can be called by anything inside the same global scope.
I have solved my problem with using an arrow function on parameter of c.
The way your functions are defined shows that c is nested inside of b which effects the scope when the function executes. First, you would have to figure out a way to call function c. Since it is inside of function b, you will first need to call function b to get to function c. Accessing function c is not possible with your code.
The below code would allow you to call function c, which then calls function a.
function a() {
console.log("i am a")
}
function b() {
this.c = function() {
//call function a here
window.a();
}
return this;
}
b().c()
Say I have this code:
const old = Function
Function = function(...args) {
console.log('Hello!')
return old.apply(this, args)
}
I can then use the Function constructor like so:
new Function('return 5')
Which logs "Hello" to the console, before returning a new function which just returns 5. This is what I want, but I want to know how, or even if it's possible to, do this for normally defined functions:
function fn () {
return 5
}
And I want this function to do the same as last one (new Function...). Now, I wouldn't be surprised if this isn't even possible, but if it is, how would I do it?
function A(){
b()
c()
}
Function c has to be called after function b.
I know there's a concept in JavaScript called callback.
How do I do it in function b?
function b(cb){
//I can't put function c here, because this of c is bound to somewhere and I don't want to mess up.
}
c() will always be called after b() because you placed it there.
The real question is whether or not c() will be called before b() is finished.
If b() is not an async function, then your code is perfect. c() will be called once b() is finished.
function A(){
b(); // *not* async
c();
}
However, if b() is async in nature, you need to provide c() as a callback.
function A(){
b(c); // async
}
function b(cb){
// ...
cb(); // cb() doesn't need "this"
}
Since c() is a bound method, you need to also pass the context (this) to b().
function A(){
/* extract and save context, somehow */
b(c, context); // async
}
function b(cb, context){
// ...
cb.call(context); // cb() doesn't need "this"
}
I don't want to mess up.
If you don't want to play with context passing, you can use a Promise.
function A(){
b().then(function() {
// run "c()" only when "b()" is finished and there were no errors
c();
});
}
function b(){
// ...
// "b()" is *not* async
return Promise.resolve();
}
function b(){
// ...
// "b()" is async
var whenDone = new Promise(function(resolve, reject) {
performAsyncTask(resolve);
})
return whenDone;
}
But wait, there's more.
If you want bleeding edge tech, you can always use async/await
async function A(){
await b(); // VOILA! it's that easy
c();
}
These are the general basic strategies. Of course, you can try to mix-n-match them or try to figure out something new that suits your needs.
You can either use Promises or a callback.
In this case I'd use a callback (as it's a simple use case & promises require crossbrowser checks).
function A() {
b(c); // Pass the function 'c'
}
function c() {
// Do something else
}
function b(callback) {
// Do something
// Run callback
callback(); // This will run whatever method you passed in
}
function b(c){
doSomething();
c();
}
function a(){
b(c);
}
Your understanding is correct. The notion of the callback is when a function is complete. What you're going to have to do is to ensure that the type of input and make sure it is a function and not something different. Take a look at the following example:
function A()
{
alert('I am A function');
b(c);
}
function b(cb)
{
alert('I am "b" function');
/// At the very end, put this code:
if (typeof(cb)==='function')
{
cb();
}
}
function c()
{
alert('I am "c" function');
}
A();
Callbacks in JavaScript are functions that are passed as arguments to other functions. This is a very important feature of asynchronous programming, and it enables the function that receives the callback to call our code when it finishes a long task, while allowing us to continue the execution of the code.
var callback = function() {
console.log("Done!");
}
setTimeout(callback, 5000);
As you can see, setTimeout receives a function as a parameter, this is a callback!
In your case you can do the following:
function b(c) {
c();
}
// calling function b and sending as a parameter an anonymous function
// that will be replaced by the "c" parameter in the "b" function
b(function() {
console.log("inside c");
});
This is almost a closure, just with a little bit more tweaking and you can turn it into one.
Your question is not very clear, let me try to decipher.
If you execute
function A() { b(); c() }
function b() { /* b work */ }
function c() { /* c work */}
Then c will be called after b if by is synchronous.
In the case b is asynchronous, c will be called before b completes.
Then you need indeed a callback as a parameter of b:
function A() { b(c) }
function b(callback) { /* b work */ ; callback() }
function c() { /* c work */ }
Yet in modern js, you'd rather use a promise:
function A() {
b().then( function() {
c()
} )
}
function b() {
return new Promise( function(resolve, reject) {
/* b work */
} )
}
function c() { /* c work */ }
I have a function that return a promise. (foo in this example)
I try to call this function inside their resolve function that was declared as anonymous.
I have tried with this but this not work.
my code looks like this
var foo = function(boo) {
/* .... */
return deferred.promise;
};
var bar = 42;
foo(bar).then(function() {
foo(bar--).then(this); //"this" don't work
});
What am I doing wrong?
Thanks
The simplest way is to name the anonymous function
foo(bar).then(function fn() {
foo(bar--).then(fn);
});
You can also declare the function separately
function fn() {
foo(bar--).then(fn);
}
foo(bar).then(fn);
so a simple example would be
function a() {
alert("something");
}
anything.onclick = a; // this is without parentheses
anything.onclick = a(); // this is with parentheses
What is the difference between the two?
And one thing more: if I define the same function but this time return false, will it work?
function a(){
alert("something");
return false;
}
The difference is that a() calls the function while a is the function.
console.log( a() ); // false
console.log( a ); // function() {...}
To make it clear what technically happens when you use the second part of your example, let's redefine alike this:
a = function() {
return 100;
};
and set the event handler:
anything.onclick = a();
f() not only calls the function f but returns its return value. So when setting a variable or object property to a function call, the return value of the function call will be assigned. So the above statement is effectlively equivalent to:
anything.onclick = 100;
which doesn't make sense and might cause an error. If a function doesn't have a return value, its return value is implicitly undefined.
However, if you had set a variable equal to a without calling it, it would be the same as setting a regular function expression to that variable:
var a = function() { ... },
b = a; // b = function() { ... }
b would perform the same operation as a would.
So in your example go with the first one because it makes sense! The only case in which you would assign the return value of the function call to an event handler is if the function returns another function. For instance:
var x = function(xyz) {
return function() {
console.log(xyz);
};
};
anything.onclick = x("Hello World"); // = function() {
// console.log("Hello World");
// }
Assigns reference:
anything.onclick = a; //assigns a reference
With your function it is:
anything.onclick = function() {
alert("something");
}
Executes method and assigns the returned result
anything.onclick = a(); //calls the method and assigns whatever is returned.
With your function it is:
anything.onclick = false;
The parenthesis at the end of the function is the permission for javascript engine to execute the function. If you don't supply it, it won't be executed at all.
If you do x=a() you are invoking the function but if you do x=a you are passing a pointer to a function
long story short:
Let's say we have
function f(){} or f = function(){}
If you now write
someFunction(f());
it will call f() and whatever f() returns will be passed as argument to someFunction().
If you write
someFunction(f);
on the other hand (when defined like the latter), f will be passed to someFunction() as (a variable holding) the function.
This could be used e.g. if the function is supposed to be used later on but maybe can't be called some other ('normal') way.
( Of course, depending on language, "function" could obviously be a "method" and the language could not even have function-variables or however you call it! )
( off topic: note that this answer says the same as the other answers because that is THE true answer but I did not want to edit the other answers because each may be found differently helpful by different people )