簡體   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