$ .when与jQuery延迟数组有时多次调用.always

时间:2012-07-23 04:29:16

标签: jquery coffeescript jasmine jquery-deferred

我的生产代码有这一块逻辑,是从CoffeeScript编译的:

results = [];
results.push(slowOpA());
results.push(slowOpB());
results.push(slowOpC());
results = _.flatten(results);
$.when.apply($, results).then(onComplete).fail(onError).always(function() {
    $(document).trigger('stop')
});

我希望这首先按顺序调用所有slowOp *方法,然后调用onCompleteonError一次,最后调用always一次。这就是我用Jasmine测试的内容:

@stopSpy = jasmine.createSpy '<stopSpy>'
$(document).bind 'stop', @stopSpy
...
@lastPromise = new $.Deferred()
spyOn('slowOpA').andReturn new $.Deferred().resolve()
spyOn('slowOpB').andReturn new $.Deferred().resolve()
spyOn('slowOpC').andReturn @lastPromise
...
@lastPromise.resolve()
expect(@stopSpy).toHaveBeenCalledOnce()

100次中有99次有效,但不时会有2或3次来电:

Expected spy on <stopSpy> to have been called once, but was called '2' times

我错过了什么吗?或者这是jQuery / Jasmine中一些模糊的竞争条件?

1 个答案:

答案 0 :(得分:1)

我对Jasmine不熟悉,但您的JavaScript代码是正确的;我在jsFiddle中模拟了一些相同的东西,它按预期工作。我将'then(onComplete)'换成'done(onComplete)'和'then(onComplete,onError)',但都按预期工作。我假设slowOpX的返回延迟/承诺。下划线(?)_. flatten(结果)是多余的,但我怀疑这会导致任何问题。