
Javascript asynchronous functions and this keyword
When using asynchronous functions in classes, a problem often arises when it is impossible to access the class object that calls the function in the function body. This is clearly seen in the ajax example (using jQuery):
To solve this problem, there is an apply function in javascript that allows you to call any function in the context of our object - i.e. this will be what we say. It remains only to make a callback function, which will generate an asynchronous function:
object - the object that will be substituted into this
fnc - the executed function
arguments - the standard object of the function arguments
Now the result will be like this:
It is not necessary to transfer the function of an object as a function, you can create a function "on the fly":
In the previous example, we lost the object that called the success function (the internal jQuery object), but often there is a need to use the calling object. For example, in HTML element events:
In this example, the click event of the button HTML element is raised. In order to save the object of the calling function (in this case, the HTML element of the button), the callback function will take the following form:
Thus, the caller is passed as the first argument to the function, and the remaining arguments are passed in the same order. The result will be as follows:
function Loader()
{
this.load = function()
{
$.ajax({
url: '/test.php',
success: function(data, textStatus, jqXHR) {
// здесь уже никак нельзя обратиться к объекту класса
console.log(this); // this содержит внутренний объект jQuery,
// вызывающий функцию success
}
});
}
}
(new Loader()).load();
To solve this problem, there is an apply function in javascript that allows you to call any function in the context of our object - i.e. this will be what we say. It remains only to make a callback function, which will generate an asynchronous function:
function cb(object, fnc)
{
return function() {
return fnc.apply(object, arguments);
}
}
object - the object that will be substituted into this
fnc - the executed function
arguments - the standard object of the function arguments
Now the result will be like this:
function Loader()
{
this.load = function()
{
$.ajax({
url: '/test.php',
success: cb(this, this.onLoad)
})
}
this.onLoad = function(data, textStatus, jqXHR)
{
console.log(this); // this теперь содержит объект класса Loader
}
}
(new Loader()).load();
It is not necessary to transfer the function of an object as a function, you can create a function "on the fly":
cb(this, function(data, textStatus, jqXHR) {
console.log(this);
});
Saving the original this object
In the previous example, we lost the object that called the success function (the internal jQuery object), but often there is a need to use the calling object. For example, in HTML element events:
function Button()
{
this.render = function()
{
var submit = $('
In this example, the click event of the button HTML element is raised. In order to save the object of the calling function (in this case, the HTML element of the button), the callback function will take the following form:
function cb(object, fnc)
{
return function() {
var args = [this];
for (var i in arguments) args.push(arguments[i]);
return fnc.apply(object, args);
}
}
Thus, the caller is passed as the first argument to the function, and the remaining arguments are passed in the same order. The result will be as follows:
function Button()
{
this.render = function()
{
var submit = $('