我知道在摘要周期中调用$digest
或$apply
手动会导致“$digest 已经在进行中”错误,但我不知道为什么我在这里得到它。
这是一个包装服务的单元测试$http
,该服务很简单,它只是防止对服务器进行重复调用,同时确保尝试进行调用的代码仍然获得预期的数据。
angular.module('services')
.factory('httpService', ['$http', function($http) {
var pendingCalls = {};
var createKey = function(url, data, method) {
return method + url + JSON.stringify(data);
};
var send = function(url, data, method) {
var key = createKey(url, data, method);
if (pendingCalls[key]) {
return pendingCalls[key];
}
var promise = $http({
method: method,
url: url,
data: data
});
pendingCalls[key] = promise;
promise.then(function() {
delete pendingCalls[key];
});
return promise;
};
return {
post: function(url, data) {
return send(url, data, 'POST');
},
get: function(url, data) {
return send(url, data, 'GET');
},
_delete: function(url, data) {
return send(url, data, 'DELETE');
}
};
}]);
单元测试也非常简单,它用于$httpBackend
预期请求。
it('does GET requests', function(done) {
$httpBackend.expectGET('/some/random/url').respond('The response');
service.get('/some/random/url').then(function(result) {
expect(result.data).toEqual('The response');
done();
});
$httpBackend.flush();
});
这done()
会随着“$digest already in progress”错误的调用而爆炸。我不知道为什么。我可以通过包装done()
像这样的超时来解决这个问题
setTimeout(function() { done() }, 1);
这意味着done()
将在 $digest 完成后排队并运行,但这解决了我想知道的问题
- 为什么 Angular 首先处于摘要循环中?
- 为什么调用
done()
会触发此错误?
我在 Jasmine 1.3 上运行了完全相同的测试,这只是在我升级到 Jasmine 2.0 并重写测试以使用新的 async-syntax 之后发生的。