Reputation: 780
Ive a jquery function that obtains text from all nodes of a particular class using the jquery .each() selector:
function get_text()
{
$(".my_class").each(function ()
{
$this = $(this);
node_text = $this.text();
console.log(node_text);
})
}
That works as expected. Next, I want to send the text to a php script using .ajax() :
function get_php_text(node_text)
{
let url = `myphp.php?string_text=${node_text}`;
$.ajax(
{
url: url,
success: function(result)
{
console.log(result);
}
});
}
That function also works as expected.
When I run the following:
function get_text()
{
$(".my_class").each(function ()
{
$this = $(this);
node_text = $this.text();
get_php_text(node_text);
})
}
I run into a problem as get_php_text() is not waiting for each .each() iteration to complete.
How can I rewrite the get_text() function so that it waits for the get_php_text() to return before going to the next iteration?
Upvotes: 1
Views: 269
Reputation: 8597
Another example is using closures, but it should be used if you want to send data every time an iteration occurs in $.each.
function get_text() {
function SampleClosure(node_text) {
let url = `myphp.php?string_text=${node_text}`;
$.ajax({
url: url,
success: function(result) {
console.log(result);
}
});
}
$(".my_class").each(function() {
$this = $(this);
node_text = $this.text();
SampleClosure(node_text);
})
}
So, what happens above is, every element, the text is extracted and passed to a Closure which is an expression that can reference variables within its scope when it was first declared. So even if you change the passed variable before the Ajax call is sent, it'll still use the old passed text and function will execute. I like to (which is wrong) think of it as creating an instance of a function with passed data which once completed is taken care of by GC, and within the loop, multiple instances of the function are created within their own memory allocation. As I said, this is how I see it, and what I said might be wrong, but theoretically this is how the process appears to me and works.
Upvotes: 2
Reputation: 1028
You can make it so that the iterating is done inside the success handler of your ajax call, by making get_php_text()
recursive. This way the next iteration will only occur after the previous one has finished its ajax request.
function get_text() {
let node_text_array = [];
$(".my_class").each(function() {
node_text_array.push($(this).text());
});
get_php_text(node_text_array);
}
function get_php_text(node_text_array) {
if (node_text_array.length>0) {
let node_text = node_text_array.splice(0,1);
let url = 'myphp.php?string_text=${node_text}';
$.ajax({
url: url,
success: function(result) {
console.log(result);
get_php_text(node_text_array);
}
});
}
}
Upvotes: 2