Reputation: 1572
Is there a way to do 1 request and write
every time an response comes? I want to make 1 request and inside to do 10 requests to the db and when an query responses to write on the html
? How can i achieve that?
my api
routeHandlers = () => {
let data: Array<any> = [];
this._router.get('/api/countdetails/:uid', (req, res) => {
let uid = req.params.uid;
console.log(req);
for (let i = 0; i < 10; i++) {
data.push({
id: 'request' + i,
startTime: performance().toFixed(3)
});
let query = `SELECT ${i} AS ID, * FROM CountDetails WHERE UID='${uid}'`;
this._db.execQuery(query, (err, row) => {
if (err) throw err;
for (let i = 0; i < data.length; i++) {
Object.keys(data[i]).forEach((val, idx) => {
if (val === 'id') {
if (data[i][val] === 'request' + row[0]['ID']) {
data[i].endTime = performance().toFixed(3);
data[i].ellapsed = (performance() - data[i]['startTime']).toFixed(3);
res.write('<tr><td>' + data[i]['ellapsed'] + '</td></tr>');
}
}
});
}
});
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.end();
}
});
}
and my html
<div>
<input type="text" id="iterations" />
<button type="button" id="btn">send</button>
</div>
<div>
<table id="tbl">
<tbody>
</tbody>
</table>
</div>
<script>
var inputValue = document.getElementById('iterations');
var btn = document.getElementById('btn');
var array = [];
btn.addEventListener('click', function () {
sendRequest(function (xhttp) {
console.log(xhttp.responseText);
})
});
function sendRequest(callback) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
callback(xhttp);
}
};
xhttp.open("GET", "http://localhost:3000/api/countdetails/EAACCDF4-EBC3-4B11-8654-98878BFC4B7B", true);
xhttp.send({ times: 10});
}
</script>
Upvotes: 1
Views: 119
Reputation: 6558
First don't use i
for nested for
.
So you want to call res.end()
once all the database calls are finished. This can be done in a variety of ways, but I will give you a quick one with a little tweak of your code. This is the code snippet and the explanations come after: (also read comments in code)
routeHandlers = () => {
/* 1) we can use the indicator to determine when all the async requests are finished */
let indicator = 0;
let data = [];
this._router.get('/api/countdetails/:uid', (req, res) => {
/* 2) always set the indicator to 0 on a new request */
indicator = 0;
let uid = req.params.uid;
for (let i = 0; i < 10; i++) {
data.push({
id: 'request' + i,
startTime: performance().toFixed(3)
});
let query = `SELECT ${i} AS ID, * FROM CountDetails WHERE UID='${uid}'`;
this._db.execQuery(query, (err, row) => {
if (err)
throw err;
for (let j = 0; j < data.length; j++) {
Object.keys(data[j]).forEach((val, idx) => {
if (val === 'id') {
if (data[j][val] === 'request' + row[0]['ID']) {
data[j].endTime = performance().toFixed(3);
data[j].ellapsed = (performance() - data[j]['startTime']).toFixed(3);
res.write('<tr><td>' + data[j]['ellapsed'] + '</td></tr>');
}
}
});
}
/* 3) here check if indicator is 10 and if yes then all the database calls should be finished */
indicator++;
if (indicator === 10) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.end();
}
});
}
});
}
In short words I will use integer variable as an indicator how many database calls are finished and once number 10 is reached I consider all are done and end the response.
1) Declare indicator
variable which will help us to determine when the job is ready;
2) Reset indicator on each coming request (you might also think resetting data
)
3) Once database call is finished increment indicator
and check its value -> if it is 10 then we are done and end the response.
That's it, short and simple. Let me know if something is unclear.
Upvotes: 1