I have an each() with inside a function with callback. I would like that each() will be synchronous by callback. I post here my example
function insRow(rif, callback){
setTimeout(function() {
$(rif+" tr:nth-child(2)");
var newtr=$(rif+" tr:nth-child(2)").clone();
$(".insTo").append(newtr);
$(rif+" tr:nth-child(2) td:nth-child(1)").text("O");
$(rif+" tr:nth-child(2) td:nth-child(3)").text("O");
$(rif+" tr:nth-child(2) td:nth-child(5)").text("O");
if (callback) { callback(true); }
},1000);
}
var go=true;
$(".insFrom tr:not(:first-child)").each(function(){
if(go){
go=false;
$(".middle tr:nth-child(2) td:nth-child(1)").text($(this).find("td:nth-child(1)").text());
$(".middle tr:nth-child(2) td:nth-child(3)").text($(this).find("td:nth-child(2)").text());
$(".middle tr:nth-child(2) td:nth-child(5)").text($(this).find("td:nth-child(3)").text());
insRow(".middle", function(callback){
if(callback){
go=true;
}
});
}
});
table td{
border:1px solid black;
min-width:50px;
text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table class="insTo">
<tr><td>A</td><td>B</td><td>C</td><td>D</td><td>E</td></tr>
</table>
<br><br>
<table class="middle">
<tr><td>A</td><td>B</td><td>C</td><td>D</td><td>E</td></tr>
<tr><td>O/td><td>X</td><td>O</td><td>Y</td><td>O</td></tr>
</table>
<br><br>
<table class="insFrom">
<tr><td>A</td><td>C</td><td>E</td></tr>
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>4</td><td>5</td><td>6</td></tr>
<tr><td>7</td><td>8</td><td>9</td></tr>
</table>
My code is more complicated than this and I must to pass data from "insFrom" to "middle" and than combined to "insTo". Now my result is only the first row combined, but I want to have all combined.
You probably need to await the loop (this is new cool js stuff [ won't work in old browsers]):
//we need to define a block of async code
(async function (){
//.forEach won't work, we need a real array and a real for loop
for(const el of $(".insFrom tr:not(:first-child)").toArray()){
$(".middle tr:nth-child(2) td:nth-child(1)").text($(el).find("td:nth-child(1)").text());
$(".middle tr:nth-child(2) td:nth-child(3)").text($(el).find("td:nth-child(2)").text());
$(".middle tr:nth-child(2) td:nth-child(5)").text($(el).find("td:nth-child(3)").text());
//now the real magic:
//the code halts here, and resumes when the callback gets called
await new Promise(callback => insRow(".middle", callback));
}
})();//the async code block is called emmidiately
Or you need some callback hell:
var els = $(".insFrom tr:not(:first-child)");
//an IIFE, used as an entry point for continuing
(function next(i){
//if index is out of scope terminate
if(i >= els.length) return;
var el = els[i];
$(".middle tr:nth-child(2) td:nth-child(1)").text($(el).find("td:nth-child(1)").text());
$(".middle tr:nth-child(2) td:nth-child(3)").text($(el).find("td:nth-child(2)").text());
$(".middle tr:nth-child(2) td:nth-child(5)").text($(el).find("td:nth-child(3)").text());
insRow(".middle", function(callback){
if(callback){
next(i+1);//proceed with the next element
}
});
})(0);//start immediately at index 0