1

I have this structure of code:

connection.query(query1,function(err,rows) {
    var response = [];
    //doing something with rows
    rows.forEach(function(item) {
        connection.query(queryItem,function(err,rows) {
            //doing something
            result = rows[0].field;
            //and want to push it to an array
            response.push(result);
        });
    });
    console.log(response); //empty
});

I know that forEach is blocking but query is non-blocking. I tried to use promises:

connection.query(query1,function(err,rows) {
    var response = [];
    //doing something with rows
    rows.forEach(function(item) {
        var promise = new Promise(function(resolve,reject) {
            connection.query(queryItem,function(err,rows) {
                //doing something
                result = rows[0].field;
                //and want to push it to an array
                resolve(result);
            });
        });
        promise.then(function(result) {
            console.log(result); //ok
            response.push(result) //not ok, result is empty
        });
    });
    console.log(response); //empty
});

But it's not helped. How can I push value into array from non-blocking function and use it after?

2
  • Is that native promise or bluebird? Commented Oct 2, 2015 at 22:06
  • I'm a newbie in node. require('promise'); May be native, i don't know =) Commented Oct 3, 2015 at 9:46

1 Answer 1

4

Creating promises is a step in the right direction, but you need to take it a step further by aggregating the promises into an array and passing to Promise.all, and then waiting for them all to finish before trying to access response.

connection.query(query1,function(err,rows) {
    var response = [];
    //doing something with rows
    Promise.all(rows.map(function(item) {
        var promise = new Promise(function(resolve,reject) {
            connection.query(queryItem,function(err,rows) {
                //doing something
                result = rows[0].field;
                //and want to push it to an array
                resolve(result);
            });
        });
        return promise.then(function(result) {
            console.log(result); //ok
            response.push(result) //ok
        });
    }).then(function () {
        console.log(response); //not empty
    });
});
Sign up to request clarification or add additional context in comments.

3 Comments

Note that this results in sending n queries to your database a the same time, it would likely be better to combine them all into a single transaction, which would also remove the need for promises in this case. Disregard if this is a SELECT statement, in which case you might be able to just make a single query that gets the data and then group by item instead. Sending queries in a loop like this is usually a bad idea performance-wise.
It's work! But if I do "console.log" outside Promise.all - this is empty. Is it mean that I must put my next code into promise.then? Or are there any way?
And thank you for advice about complex SELECT-query. I'll try it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.