简体   繁体   中英

How to achieve sequential execution of code containing both testing and asynchronous function calls

I want to execute four blocks of code sequentially and conduct test during this sequential execution. The challenge is that the blocks contain calls of asynchronous functions.

I cannot seem to wrap my head around promises to use them properly and I just seem stuck after spending several hours on the block of code.

// Store current log of drone visits for DJI Phantom 4
db.query("SELECT COUNT(drone_id) FROM Drone_Visits WHERE drone_id = 2;", function(err, rows) {
    if (err) {
        console.log(err);
    }
    else {
        current_drone_visits = rows[0]['COUNT(drone_id)'];                  
    }
});

it("should return status 200 (OK) when requesting route for this function", function(done) {
    request.get("/product/DJI/Phantom_4").query({brand: dji_brand, model: dji_model}).end(function(err, res) {
        assert.equal(res.status, 200);  
        done();
    }); 
});


db.query("SELECT COUNT(drone_id) FROM Drone_Visits WHERE drone_id = 2;", function(err, rows) {
    if (err) {
        console.log(err);
    }
    else {
        updated_drone_visits = rows[0]['COUNT(drone_id)'];                  
    }
});

it("should increment the value of drones visited in the database", function(done) {
    console.log("A - " + current_drone_visits);
    console.log("B - " + updated_drone_visits);
    assert.equal(current_drone_visits + 1, updated_drone_visits);
    done();
});

What should I do here if I want to chain my callbacks such that they execute only after the previous function has finished?

Use async.js if you are comfortable with callbacks, or use Promises, you can chain them in order to synchronise you functions.

just wrap your callback in a function that return a promise like this

    function P(){
  return new Promise((resolve, reject)=>{
      db.query("SELECT COUNT(drone_id) FROM Drone_Visits WHERE drone_id = 2;", function(err, rows) {
        if (err) reject(err);  
        else {          
          resolve(rows[0]['COUNT(drone_id)'])
        }
      });
  })
}

function T1(data){
  //data in this case will be the result of the P() function 
  return new Promise((resolve, reject)=>{      
    request.get("/product/DJI/Phantom_4").query({brand: dji_brand, model: dji_model}).end(function(err, res) {
      if(err || res.status==200) reject(err);  
        resolve();
     });
  })
}

P()
  .then(T1)
  .then(...)
  .catch((err)=>{ 
    //handle error here
  })

sry for the bad formatting

What should I do here if I want to chain my callbacks such that they execute only after the previous function has finished.

This code does it for you:

describe ('test', function () {

    this.timeout(6000);

    it ('test', function(done) {

            var query1 = new Promise (function (resolve, reject) {

               db.query("SELECT COUNT(drone_id) FROM Drone_Visits WHERE drone_id = 2;", function(err, rows) {
                    if (err) {
                        reject(new Error('rejected query1'));
                    } else {
                        var current_drone_visits = rows[0]['COUNT(drone_id)'];
                        resolve(current_drone_visits);
                    }
                });
            })

            .then(function(current_drone_visits){

                var request1 = new Promise (function (resolve, reject) {

                   request.get("/product/DJI/Phantom_4").query({brand: dji_brand, model: dji_model}).end(function(err, res) {
                        if (err) {
                            reject(new Error('rejected request'));
                        } else {
                            resolve(res);
                        }
                    })
                })

                .then(function (res) {

                    try {
                        assert.equal(res.status, 200);  
                        return current_drone_visits;
                    }
                    catch (err) {
                        done (err);
                    }
                })

                .catch(function(err) {
                    return Promise.reject(err);
                })

                return request;
            })

            .then(function(current_drone_visits) {

                var query2 = new Promise (function (resolve, reject) {

                   db.query("SELECT COUNT(drone_id) FROM Drone_Visits WHERE drone_id = 2;", function(err, rows) {
                        if (err) {
                            reject(new Error('rejected query2'))
                        } else {
                            resolve();
                        }
                    })
                })

                .then(function () {
                    var updated_drone_visits = rows[0]['COUNT(drone_id)']; 
                    var bundled = [current_drone_visits, updated_drone_visits];
                    return bundled;
                })

                .catch(function(err) {
                    return Promise.reject(err);
                })

                return query2;
            })

            .then(function(bundled) {

                var current_drone_visits = bundled[0];
                var updated_drone_visits = bundled[1];

                console.log('A - ' + current_drone_visits);
                console.log('B - ' + updated_drone_visits);
                assert.equal(current_drone_visits + 1, updated_drone_visits);
                done()
            })

            .catch (function (err) {
                done(err);
            })
        })      
    })

You can use the this.timeout(6000) to determine how long Mocha will wait for your asynchronous code to complete. The default value is 2000 ms which may or may not be sufficient in your case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM