BenSmith
BenSmith

Reputation: 431

nodeJS: Promise executing before for loop finishes, callback stack

I'm using a promise to create a response to Postman of the result array; however, resolve() gets called before the forEach loop finishes, while the resolve() is outside the forEach loop. I feel it's due to the callback stack functionality.

How do I execute the resolve() after the forEach loop is finished executing, considering the callback stack?


(server.js):

logServer.post('/log/asset/audit/', function(req,res){ 
  console.log('--- starting log/asset/audit');

  logDB.collection('logs')
    .find({"transaction.assetName" : assetName, "transaction.assetOwner" : assetOwner})
    .toArray( (err, result) => {
      let token = JSON.parse(JSON.stringify(self_jwt_body)); 

      var JSONPromise = new Promise((resolve, reject) => { //initialization      

      result.forEach(function(element, index, array) {  
        console.log('- before request.post');

            request.post({
              url: `${dc_link}/audit`, //includes dc_IP, dc_port and /audit
              headers: {     
                "jwt": jwt.sign(token, jwtSecret) 
              }
            }, function(error,response,body) {
              console.log('path 0');
              let parseBody = JSON.parse(body);

              console.log('path 3');
              result[0].transaction.signature = parseBody.additionalData;
              console.log('result: ', result);
              //**HERE
            });
         });
         //**HERE
        resolve();

      };  //end callback

        JSONPromise.then(() => {  //finalization  //**HERE
        respondWithJSON(200, req.body.result, req.body.description, res, result); 
        console.log('end log/asset/audit');
        };
   });
});

Upvotes: 1

Views: 79

Answers (2)

Lpc_dark
Lpc_dark

Reputation: 2952

Should be closer to what you need.

logServer.post('/log/asset/audit/', function (req, res) {
    console.log('--- starting log/asset/audit');

    logDB.collection('logs')
        .find({ "transaction.assetName": assetName, "transaction.assetOwner": assetOwner })
        .toArray((err, result) => {
            let token = JSON.parse(JSON.stringify(self_jwt_body));

            var JSONPromise = new Promise((resolve, reject) => { //initialization      

                let async_result = result.map(function (element, index, array) {
                    console.log('- before request.post');

                    return new Promise((resolve,reject)=>{
                        request.post({
                            url: `${dc_link}/audit`, //includes dc_IP, dc_port and /audit
                            headers: {
                                "jwt": jwt.sign(token, jwtSecret)
                            }
                        }, function (error, response, body) {
                            console.log('path 0');
                            let parseBody = JSON.parse(body);

                            console.log('path 3');
                            result[0].transaction.signature = parseBody.additionalData;
                            console.log('result: ', result);
                            resolve();
                            //**HERE
                        });
                    });
                });
                //**HERE

                return Promise.all(async_result);


            });  //end callback

            JSONPromise.then(() => {  //finalization  //**HERE
                respondWithJSON(200, req.body.result, req.body.description, res, result);
                console.log('end log/asset/audit');
            });
        });
});

Upvotes: 0

SLaks
SLaks

Reputation: 888107

You're calling resolve() before any of the responses arrive.

You need to wrap request() in a function that returns a promise (of a single request), then write

Promise.all(result.map(e => requestPromise(...)))

To wait for all of those promises.

Upvotes: 2

Related Questions