Callback's rest operator args available in higher-order functions - javascript

I've recently stumbled upon code (below) using the ES6 rest parameter and there is something that I cannot fully grap:
--> it's a debounce function that is used to limit the number of API calls when the user types in an input field.
--> the debounce function takes in a callback function and a delay param (which is set to 250 by default).
--> the debounce function uses a wrapper for the callback to make sure it is called only after a delay. The callback function is called in the wrapper with the arguments passed to updateDebounceText.
I understand the code and the overall logic, but what trips me out is how can the wrapper in the debounce function have access to the ...args of the callback? I know that a child function can directly access the rest parameter of the parent function, but in this case, the parent function accesses the rest parameter of the callback.
I'm sure the answer is pretty simple but I can't 100% grasp for now! any help would appreciated!
thanks a lot!
function debounce(cb, delay = 250) {
let timeout
return (...args) => {
clearTimeout(timeout)
timeout = setTimeout(() => {
cb(...args)
}, delay)
}
}
const updateDebounceText = debounce((text) => {
console.log(text)
})
input.addEventListener("input", (e) => {
updateDebounceText(e.target.value);
})

Related

what is the difference between a function and an arrow function that calls a function

const mapDispatchToProps = dispatch => {
return {
buyCake: () => dispatch(buyCake())
}
}
When I run my program by changing the third line to
buyCake: dispatch(buyCake())
it doesn't work. What is the difference between these two approaches and why do you need the () =>
buyCake: () => dispatch(buyCake())
This will declare buyCake to be a function that takes no arguments, and calls dispatch in its body; but buyCake itself won't be called until you explicitly call it.
It's more or less conceptually equivalent to:
function buyCake() {
dispatch(buyCake());
}
I say conceptually because there are some technical differences between regular functions and arrow functions (a.k.a. lambdas, lambda expressions); see this for more info.
On the other hand
buyCake: dispatch(buyCake())
will set buyCake to the result of the call to dispatch (dispatch will be called immediately, right there).
It's the same as the difference between:
const getSinPI = () => Math.sin(Math.PI); // a function named `getSinPI`
getSinPI(); // returns approx. 0
and
const sinPI = Math.sin(Math.PI); // a variable storing the result (approx. 0)
The mapDispatchToProps function returns an object containing, as properties, ad-hoc wrapper functions that you defined, that perform calls to dispatch in some way that makes sense for your application. This object is then used to place these functions on the props object (the different dispatch calls are "mapped" onto these wrappers - thus the name). This is so that you can make use of dispatch in a more convenient way, using wrapper functions with names that more closely reflect what your application is doing.

Why do we need callback instead of calling directly inside the function? in JS

I just realized that I do not understand javascript enough, despite the fact that I have been coding it for some time.
What I am not comfortable is Javascript Async.
until now I have been using callback and promise, because documentations and tutorials did it so as below.
$.get("some/url", function() {
// callback body
})
axios.get('some/url').then(res => {
console.log(res.data);
});
arr.map(element => console.log(element))
I know callback is used to my our code asynchronous
function doSomething(cb) {
console.log("this function receives callback function");
cb();
}
but what if we just call the function inside the function manually
function func1() {
// function body
}
function doSomething() {
console.log("this function receives callback function");
func1();
}
What I thought is as long as function is called at the right time, we do not have to use callback.
or is it because callback does its work while some other operations are going on?
If so, doesnt it break the principle of javascript as single threaded?
because its doing two things at the same time.
besides, do people use promise over callback function because of its readability and you could use Promise.all() ?
I feel like I am missing a core advantage of using promise.
Kindly please help me understand better.
If you don't use a callback, then you can only call func1(). The original doSomething() is more general, since you can call different functions depending on what the caller needs.
function func1() {
// function body
}
function func2() {
// function body
}
doSomething(func1);
doSomething(func2);
Is exactly the difference between hard coding data in your code or getting it dynamically.
In backend for example you make the code so it can serve different users different needs... at the same time, the same code...
So in this example:
function doSomething(cb) {
console.log("this function receives callback function");
cb();
}
you can build a functions that serve different users different information depending on the cb it receives...
in this example:
function func1() {
// function body
}
function doSomething() {
console.log("this function receives callback function");
func1();
}
it just runs a specific function func1 and that's it
It is all about reusability. If you call pass your callback into the utility function, in your example it is doSomething, you will not be able to reuse doSomething function in other parts of your program. You have just created a tight coupling between two functions.
If you program to the interface, and define which kind of callback you are expecting in your doSomething function, you will be able to use this doSomething function anywhere. It will not have to know which exact function to call, it will just concern about having a callback which expects n parameters in some order which.

JavaScript anonymous function callback and redux-saga .next()

I've been going through several JavaScript concepts now, including a several react conveys, and there's a couple of questions that I am wondering and wishing to get help from you guys.
Suppose we have a function name sum:
const sum = (a,b) => a + b
Question 1:
I've seen a lot of anonymous functions being called to call another function, I am wondering the reason why we do that instead of calling that specific function directly. For example:
Instead of using
onClick = {sum}
we use:
onClick ={() => sum}
Also, in the react course, I am wondering why do we call mapDispatchToProps like:
Increment: () => dispatch({type: 'INCREMENT'})
but not:
increment: dispatch({type: 'INCREMENT'})
Question 2:
When do we use sum() or sum in the click event, for example:
onClick = {sum()} OR onClick = {sum}
Question 3:
As we know that Redux-Saga implements generator function, but as from what I know, generator function when it has more than one yield, it requires next() in order to go on.
However, in Redux-Saga, I don't see the use of next(), is that because the Sagas has already automatically called next() in it's function?
Thanks guys. Much appreciated!
For the question 1 and 2, the onClick property expects a event handler (which is a function definition) that has the event as the first parameter and should not return anything.
When the button is clicked, the onClick function invokes, passing the event as the first argument.
Read more at Handling Events in React
const sum = (a, b) => a + b
// an `event` will be passed as the first argument, the second argument gets undefined
onClick={sum}
// you could opt out the `event` parameter and call `sum` with your arguments
onClick={() => { sum(5, 10) }}
onClick={() => sum(5, 10)} // this will return the value of `sum(5, 10)` to the caller of onClick, which is not useful since the caller don't expect that
=> Using anonymous callback gives you the ability to call the function with specific arguments
// invalid usages, calling the function immediately which will assign the returned value to `onClick`, and the that returned value is not a function definition
onClick={sum(5, 10)}
increment: dispatch({type: 'INCREMENT'})
For the question 3, redux-saga acts as a generator runner that has handled calling next() for you. You only need to define the generator function (in combination with using their redux-saga effects)

How the callback is executed in this function?

const getData = (cb) => {
setTimeout( () => {
cb({ data: ['there', 'is', 'stuff', 'here'] })
}, 100)
}
getData( data => {
console.log(data);
});
Here is the example of the javascript callback. Could some one let me know how this functions is executed into the javascript callback?
Here what is the function inside getData(cb) ? How it will be executed ? How the functions is passed as callback inside cb and return to the console.log
Regards.
The function inside getData is a callback being passed to setTimeout, which is one way to schedule a call to a function to happen in the future. In this case, it's asking for that callback to happen roughly 100ms later. getData returns before that happens.
The setTimeout callback is a closure¹ over the context where it's created, which means it has access to cb even after getData has returned. So when the browser's timer calls the callback, the callback can call cb. The call to cb uses an object literal to create an object to pass to cb.
In the call to getData, the author is passing a function as cb that logs the data it receives.
So:
getData is called, passing in a function that will log the argument it gets.
getData calls setTimeout to schedule a callback in about 100ms, passing in another function for the timer to call.
getData returns.
About 100ms later, the browser's timer subsystem triggers a call to the callback passed to setTimeout.
That callback creates an object and calls cb, passing the object to it.
That callback (the one passed to getData) logs the data object it receives.
¹ "closure" — see: SO, my anemic blog
In order to understand the code you can just simplify it by naming the anonymous functions. One example could be:
function logData(data) {
console.log(data);
}
const getData = (cb) => {
// `cb` is `logData` function when `getData` is called
function timeoutCallback() {
var data = { data: ['there', 'is', 'stuff', 'here'] };
cb(data);
}
setTimeout(timeoutCallback, 100)
}
getData(logData);
Does that make sense?
1- first global execution context created
2- get data function will be called then it will wait for 10 seconds inside the event loop then it will be come to execution context and printed to console.

knockoutjs execute callback immediately after subscribe to observable

I have:
this.selectedItem.subscribe(model => {
this.currentEditor(this.editors.find(e => e.canRender(model)));
this.currentEditor().render(model);
});
where this.selectedItem already has a value.
Is it possible to run callback (but leaving it anonymous) immediately after subscribing?
You can call valueHasMutated on this.selectedItem, so
this.selectedItem.valueHasMutated()
However this not just runs your callback but also notify everybody else, e.g bindings, computeds etc.
So you are propably better to have a named function and call it when it is needed and use that also in the subscribe.
You can extract function into a variable and call it:
var changeHandler = (model) => {
this.currentEditor(this.editors.find(e => e.canRender(model)));
this.currentEditor().render(model);
};
this.selectedItem.subscribe(changeHandler);
changeHandler();

Categories

Resources