如何实现包含测试和异步函数调用的代码的顺序执行

时间:2016-10-23 20:44:25

标签: javascript testing asynchronous callback promise

我希望按顺序执行四个代码块,并在此顺序执行期间进行测试。挑战在于块包含异步函数的调用。

我似乎无法绕过承诺正确使用它们,而我在代码块上花了几个小时后似乎陷入了困境。

// 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();
});

如果我想链接我的回调以便它们只在前一个函数完成后执行,我该怎么办?

2 个答案:

答案 0 :(得分:0)

如果你对回调感到满意,可以使用async.js,或者使用Promises,你可以链接它们以便同步你的功能。

将回调包装在一个返回这样的承诺的函数中

    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
  })

表示格式错误

答案 1 :(得分:0)

  

如果我想将我们的回调链接起来,我该怎么办?   只有在上一个函数完成后才执行。

此代码适用于您:

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);
            })
        })      
    })

您可以使用this.timeout(6000)来确定Mocha等待异步代码完成的时间。默认值为2000毫秒,在您的情况下可能会或可能不够。