0

I've a promise chain in my nodejs code, I couldn't understand why the second 'then' part is being executed before the first 'then' part completes it execution. Can someone help me understand what is wrong with the below code.

    .then(model=>{
       return mongooseModel.find({})
              .then(result=>{
                return _.each(model.dataObj,data=>{
                       return _.each(data.fields,field=>{
                           if(_findIndex(result, {'field.type':'xxx'})>0)
                           {
                           return service.getResp(field.req) //this is a service that calls a $http.post
                                  .then((resp)=>{
                                        field.resp=resp;
                                        return field; 
                                     })      

                             }
                         })  
                      })
              })
              .then(finalResult=>{
                submit(finalResult); //this is being called before the then above is completely done
              }) 

    })

    function submit(finalResult){
     .....
    }

I've solved my problem by making the the changes as below

    .then(model=>{

                    return Promise.each(model.dataObj,data=>{
                           return getRequest(data.fields)
                           .then(()=>{
                           return service.getResp(field.req) //this is a service that calls a $http.post
                                      .then((resp)=>{
                                            field.resp=resp;
                                            return field; 
                                         })      

                           })
                    })                  
                  .then(finalResult=>{
                    submit(finalResult);                   
}) 

        })


        function getRequest(fields){

        return mongooseModel.find({})
                .then(result=>{
                if(_findIndex(result, {'field.type':'xxx'})>0)
                               {
                               }

                })
        }
Ajay Srikanth
  • 1,095
  • 4
  • 22
  • 43
  • This is one of the best examples of [callback hell](https://stackoverflow.com/questions/25098066/what-the-hell-is-callback-hell-and-how-and-why-rx-solves-it) I've seen in a while. Re-working your data architecture to be a little flatter might help debugging this and future issues. – wbadart Jul 24 '17 at 19:56

1 Answers1

1

At least part of your problem is here:

.then(result=>{
    return _.each(model.dataObj,data=>{

You need to return a promise if you want the .then below to wait for its completion. Currently you are returning the result of _.each, which is not a promise (_.each is not asynchronous), so the next .then just continues right away. You eventually do return what looks like a promise from service.getResp, but you are returning it to the _.each function, which doesn't do anything useful with it.

You should probably do your loops to find the field.req that you need, and return the promise outside of the loops. Something like:

.then(result => {
  let req;

  // Loop and find what you need (maybe refactor this into a function)
  // _.each ...
  //    _.each ...

  // Outside of the loops return the promise
  return service.getResp(req)
})
Frank Modica
  • 10,238
  • 3
  • 23
  • 39