2

我在测试中需要一个嵌套的 for 循环,但我迷失了整个异步方面的事情。基本上现在发生的事情是我想遍历一个数组,并一个一个地使用值并记录输出。当前发生的情况是,唯一记录的输出是我要使用的最后一个值。很难解释,所以我将演示我的代码。

// For the sake of it, all these values are strings
var arr1 = [ [1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 2, 1], [4, 1, 2, 3] ];
var arr2 = [ [a, b, c, d], [b, c, d, a], [c, d, a, b], [d, a, b, c] ];

for(var i = 0; i < arr1.length; i++){
    describe("Test", function(){
        it("Does something", function(done){
            for(var x = 0; x < arr2.length; x++){
                it("Does something else", function(done){
                    // Do stuff with arr1[i], arr2[x] etc.
                    testFunc(arr1[i], arr2[x], function(returnValue){
                        assert.strictEqual(returnValue, true, "Passed!");
                        done();
                    }
                });
            }
        });
    });
}

现在,我无法填写代码的实际作用(隐私原因),但如果有人能指出我可以完成这项工作的方法(这意味着循环testFunc()每次都等待回调)。

如果我们这样说testFunc()

function testFunc(arr1var, arr2var, callback){
    console.log(arr1var + " and " + arr2var); 
}

当我运行它时,我看到的只是传递给控制台的最终值('3 和 c')。

我一直在寻找这个,但是因为人们的例子对于他们的代码来说是如此的具体,所以尝试和适应是令人困惑的。我查看了 Node.jsAsync模块,但也没有走得太远。

如果有人可以一步一步地告诉我,或者重写上面的内容以按照我想要的方式工作,我将不胜感激。

此外,在我的实际代码中,我的数组顶部的大小不同 - 以防万一导致差异。

由于有几个人指出了这一点,我只想补充一点,如果有人有更好的方法,我完全愿意接受建议。我将运行大约 40 次测试,这将其减少到 10-15 行代码,而不是单独调用 200 行代码,所以无论人们认为什么是最好的,请随时给我建议。

4

2 回答 2

3

在您的示例中,我没有看到任何代码气味。你只需要使用async.each而不是你的 for 循环。另外,我不明白为什么需要两个 it 语句。我会做类似的事情:

var async = require('async');
var expect = require('expect.js');
var _ = require('lodash');
var arr1 = [ [1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 2, 1], [4, 1, 2, 3] ];
var arr2 = [ [1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 2, 1], [4, 2, 2, 3] ];

describe('Array tests', function() {
  async.each(arr1, function(arr1Element, callback) {
    async.each(arr2, function(arr2Element, callback2) {
      it('Tests array elements', function(done) {
        expect(_.difference(arr1Element, arr2Element)).to.be.empty();
        done();
      });
      callback2();
    });
    callback();
  });
});
于 2013-10-09T03:13:52.927 回答
2

问题是执行的第一个异步测试检查将调用 done() 并告诉 mocha 整个测试已经完成。您需要使用计算完成多少测试的代码调用 done(),然后在最后一个完成后调用 done。

for(var i = 0; i < arr1.length; i++){
    describe("Test", function(){
        it("Does something", function(done){
            var remaining = arr2.length;
            for(var x = 0; x < arr2.length; x++){
                it("Does something else", function(done){
                    // Do stuff with arr1[i], arr2[x] etc.
                    testFunc(arr1[i], arr2[x], function(returnValue){
                        assert.strictEqual(returnValue, true, "Passed!");
                        remaining--;
                        if (remaining === 0) {
                            done();
                        }
                    }
                });
            }
        });
    });
}

也就是说,我不知道 mocha 是否支持同时调用多个 it()。您可能需要在 it() 中移动两个循环。

在我看来,你在不同的点而不是彼此相邻的 for 循环似乎很奇怪,但这可能只是你正在测试的结果。

更好的办法是切换到使用 Promise 而不是异步回调,因为 Promise 可以很容易地聚合,也就是说,当一组中的所有 Promise 都完成时调用一个函数很容易。

于 2013-10-09T02:44:50.140 回答