Jasmine的beforeEach是同步的吗?

Ada*_*ner 4 javascript jasmine

如果你有多个beforeEach,他们会一个接一个地运行吗?

beforeEach(function() {});
beforeEach(function() {});
beforeEach(function() {});
beforeEach(function() {});
beforeEach(function() {});
Run Code Online (Sandbox Code Playgroud)

他们似乎会.我尝试用我的代码测试它:

describe('Directive: Statement', function() {
  var el, scope, statements;

  beforeEach(module('simulatedSelves'));
  beforeEach(module('templates'));
  beforeEach(inject(function($compile, $rootScope) {
    console.log(1);
    scope = $rootScope.$new();

    statements = [];
    scope.statement = {
      text: 'test',
      arr: []
    };
    scope.statement.parent = statements;
    statements.push(scope.statement);

    el = angular.element('<statement statement=statement></statement>');
    $compile(el)(scope);
    scope.$digest();
  }));
  beforeEach(function() {
    var counter = 0;
    console.log(2);
    for (var i = 0; i < 1000000; i++) {
      counter++;
    }
    console.log(counter);
  });
  beforeEach(function() {
    console.log(3);
  });

  it('test statement has correct properties', function() {
    // stuff
  });
});
Run Code Online (Sandbox Code Playgroud)

它记录:

1
2
1000000
3
Run Code Online (Sandbox Code Playgroud)

由于beforeEachfor循环在记录之前记录了它的东西3,我认为它是beforeEach同步运行的.真的吗?

Kri*_*ján 8

是的,所有beforeEachs都将按照您定义的顺序执行.

如果你钻进Jasmine,你最终会得到这个定义:

Suite.prototype.beforeEach = function(fn) {
  this.beforeFns.unshift(fn);
};
Run Code Online (Sandbox Code Playgroud)

当你添加describes时,Suites生成并嵌套.每个Suite都初始化为this.beforeFns = [],如您所见,添加到.请注意,unshift添加到数组的左侧,因此您希望beforeEach首先运行后面定义的s.这是固定后,当茉莉花走到孩子套件的父母,收集所有beforeEach列表,然后反转他们你想要的顺序运行.

var beforeAndAfterFns = function(suite) {
  return function() {
    var befores = [],
      afters = [];

    while(suite) {
      befores = befores.concat(suite.beforeFns);
      afters = afters.concat(suite.afterFns);

      suite = suite.parentSuite;
    }

    return {
      befores: befores.reverse(),
      afters: afters
    };
  };
};
Run Code Online (Sandbox Code Playgroud)

正如 指出的那样,我们到目前为止假设你们所有人beforeEach都是同步的.从Jasmine 2开始,您可以beforeEach像这样设置异步:

beforeEach(function(done) {
  setTimeout(function() {
    console.log('Async');
    done();
  }, 1000)
});
Run Code Online (Sandbox Code Playgroud)

在运行时,如果函数接受参数,Jasmine会向您发送done函数并异步执行.(Function.length返回函数期望的参数个数).

for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
  var queueableFn = queueableFns[iterativeIndex];
  if (queueableFn.fn.length > 0) {
    attemptAsync(queueableFn);
    return;
  } else {
    attemptSync(queueableFn);
  }
}
Run Code Online (Sandbox Code Playgroud)

attemptAsyncdone()QueueRunner移动到下一个beforeEach钩子之前等待你打电话,所以订购仍然有效!很简约.

describe('beforeEach', function() {
  var data = null;

  beforeEach(function() { data = []; });
  beforeEach(function() { data.push(1); });
  beforeEach(function(done) {
    setTimeout(function() {
      data.push('Async');
      done();
    }, 1000);
  });
  beforeEach(function() { data.push(2); });
  beforeEach(function() { data.push(3); });

  it('runs in order', function(){
    expect(data).toEqual([1, 'Async', 2, 3]);
  });
});
Run Code Online (Sandbox Code Playgroud)

  • 尽管如此,Jasmine还支持使用promises和callback的异步`beforeEach`,所以我认为它并不像这样切入式 (2认同)