How to wait to send the response of data after the forach loop is over
js I just create a 2 function to send the response var = y but unfortunately res.end() work before then my y++ works..
This code work well with for loop without mine query but when i used a query it working stop and it gives res like below. Before promise call. Loop completed. Promise resolved: 0 Next step. 13289, 2170, 2165, 2146, 2115, 2138, 2143, 2112, 1964, 2685, 6945, 2687, 2688, 2902, 2935, 2941, 3094, 3095, 3164, 3096,
var http = require('http');
var url = require('url');
var fs = require('fs');
var mysql = require('mysql');
http.createServer(function (req, res) {
var q = url.parse(req.url, true);
var end = '';
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "justcode"
});
//1. Create a new function that returns a promise
function firstFunction() {
return new Promise((resolve, reject) => {
let arr = [];
con.connect(function (err) {
if (err) throw err;
con.query("SELECT * FROM wp_posts WHERE `post_type` = 'post'", async function (err, result, fields) {
if (err) throw err;
result.forEach(element => {
arr.push(element['ID']);
});
resolve(arr)
});
});
})
}
//2. Create an async function
async function secondFunction() {
//3. Await for the first function to complete
const result = await firstFunction()
res.end(JSON.stringify(result));
};
secondFunction()
}).listen(8080);
This is the working code::::
How about this...
//1. Create a new function that returns a promise
function firstFunction() {
return new Promise((resolve, reject) => {
let y = 0
con.connect(function (err) {
if (err) throw err;
con.query("SELECT * FROM wp_posts WHERE `post_type` = 'post'", async function (err, result, fields) {
if (err) throw err;
result.forEach(element => {
console.log(element['ID']);
y++;
});
// get the results from post table
console.log('Loop completed.')
resolve(y); // <---- Resolve the promise here
});
});
// for (i = 0; i < 100; i++) {
// y++
// }
// console.log('Loop completed.')
// resolve(y) // <--- Moving this inside con.query callback
})
}
//2. Create an async function,
async function secondFunction() {
console.log('Before promise call.')
//3. Await for the first function to complete
const result = await firstFunction()
console.log('Promise resolved: ' + result)
console.log('Next step.')
res.end();
};
secondFunction()
Problem in The Original Question
con.query
is an asynchronous
execution. It accepts a callback function which then it invokes once the operation has completed. javascript
has something called runToCompletion
in which the execution of a function continues until the last statement.
When secondFunction
is invoked, it further invokes(with an await
) firstFunction
which returns a Promise
and the execution of the promise starts, but the caller secondFunction
is waiting for the promise to finish.
Inside the execution of the Promise of firstFunction
, there is a call to con.query
, which is an asynchronous
call, but isn't being waited for. Hence, after invoking the call to con.query
, the javascript execution continues further... only to encounter a resolve
after a couple of statements. A resolve
finishes the execution of the Promise of firstFunction
and control passes back to secondFunction
and then execution continues from there on. Now, since the call to con.query
will finish after sometime, and when it does, the callback function will be executed. And so we are seeing the behavior as problematic. But it's all happening as per the semantics of javascript
execution.