Search code examples
node.jspromiseknex.js

Callback function after knex is not working


From the code below, I would like to select some data, then update it if suit the conditions and finally run two urls to do some other tasks.

I can update the second knex update query, however, it failed to run any of the two post request, I wonder why?

router
    .get('/xxxx', function(req, res){
        _DB_Knex('xxx')
        .where({
            "xxxx": "xxxx"
        })
        .select('xxxx.*', 'xxx.xxx as xxx', 'xxx.xxxx')
        .leftJoin('xxxx', 'xxx.xxx', 'xxx.xxx')
        .then (function (data) {

        if(data && data.length>0){
            for(var i=0; i<data.length; i++){
                if(xxxxx){
                    var xxx = xxxxx;
                    var xxx = data[i].xxxx;
                    var xxx = data[i].xxxx;
                    var xxx = data[i].xxx;

                    if(xxx>=xxx){
                        _DB_Knex('xxxx')
                        .where({
                           xxx: "xxxx",
                           xxx: xxxx                                
                         })
                         .update({
                           xxxx : "xxxx"
                         })
                         .then(function(){
                             request.post({
                                url: `${api_url}/xxxxx/s`,
                                  body: { 
                                    xxx: xxxx
                                  },
                                  json: true
                             });

                             request.post({
                                 url: `${api_url}/xxxx/xxxx`,
                                  body: { 
                                     xxx: xxxx
                                  },
                                 json: true
                             });

                            return null;
                       });
                   }
              }
          }
        }
  }});

Solution

  • The posted code is redacted, so it's tough to show precisely how to refactor it, but there is a required change and a recommended change.

    The recommended change is to promisify the router.get(). Looking at that first...

    // get the xxx route.  return a promse that resolves to the get response
    // TODO: error handling
    function getXXX() {
        return new Promise(function(resolve, reject) {
            router.get('/xxxx', function(req, res){
                resolve(res);
            });
        });
    }
    

    Calling that...

    function theOPFunction() {
        return getXXX().then(function(res) {
            return _DB_Knex('xxx')
                .where({ "xxxx": "xxxx" })
                .select('xxxx.*', 'xxx.xxx as xxx', 'xxx.xxxx')
                .leftJoin('xxxx', 'xxx.xxx', 'xxx.xxx')
        }).then(function(data) {
            return loopAndGatherPromises(data);  // see below
        })
    }
    

    The required change is that the loop through data must gather the promises being produced in it and run them with Promise.all().

    function loopAndGatherPromises(data) {
        let promises = [];
        if(data && data.length>0){
            for(var i=0; i<data.length; i++){
                if(xxxxx){
                    var xxx = xxxxx;
                    var xxx = data[i].xxxx;
                    var xxx = data[i].xxxx;
                    var xxx = data[i].xxx;
    
                    if(xxx>=xxx){
                        promises.push(updateAndPost(data));
                    }
                }
            }
        }
        return Promise.all(promises);
    }
    
    
    // updateAndPost answers a chain of three promises update the db and
    // post to two web services. note these 3 chained promises probably
    // could be made parallel with promise.all
    function updateAndPost(data) {
        return _DB_Knex('xxxx').where({xxx: "xxxx",xxx: xxxx}).update({ xxxx : "xxxx"}).then(function(){
            return request.post({
                url: `${api_url}/xxxxx/s`,
                body: { xxx: xxxx },
                json: true
            });
        }).then(function() {
            return request.post({
                url: `${api_url}/xxxxx/xxxx`,
                body: { xxx: xxxx },
                json: true
            });
        });
    }