繁体   English   中英

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

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

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

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

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

如果要链接回调以使回调仅在上一个函数完成后才执行,该怎么办?

如果您对回调感到满意,请使用async.js,或者使用Promises,可以将它们链接起来以同步功能。

只需将您的回调包装在返回这样的promise的函数中

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

不好意思格式化

如果要链接回调以使它们仅在上一个函数完成后才执行,该怎么办。

此代码为您做到了:

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毫秒,这可能足够,也可能不足。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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