Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Timeout callback can occur in the middle of a digest cycle in Firefox #10083

@pkaminski

Description

@pkaminski

It appears that, in Firefox only, certain actions cause it to process the timeout queue on top of the current call stack. If the current call is in a digest cycle, and a $timeout with invokeApply=true gets triggered, this results in a $apply already in progress error.

See http://plnkr.co/edit/9V1jQSaszbjrt9F5ACjk?p=preview for a repro that uses window.open to trigger timeout processing. If you click on the button you'll see the following sequence in the console:

"before window open" script.js:6
"timeout" script.js:5
"Error: [$rootScope:inprog] $apply already in progress
http://errors.angularjs.org/1.3.1/$rootScope/inprog?p0=%24apply
minErr/<@http://code.angularjs.org/1.3.1/angular.js:80:12
beginPhase@http://code.angularjs.org/1.3.1/angular.js:14463:1
$RootScopeProvider/this.$get</Scope.prototype.$apply@http://code.angularjs.org/1.3.1/angular.js:14207:11
timeout/timeoutId<@http://code.angularjs.org/1.3.1/angular.js:15945:25
completeOutstandingRequest@http://code.angularjs.org/1.3.1/angular.js:4842:7
Browser/self.defer/timeoutId<@http://code.angularjs.org/1.3.1/angular.js:5215:7
$scope.click@http://run.plnkr.co/AFImpHzuwgSHuYUW/script.js:7:5
$parseFunctionCall@http://code.angularjs.org/1.3.1/angular.js:12114:15
ngEventHandler/</callback@http://code.angularjs.org/1.3.1/angular.js:22548:17
$RootScopeProvider/this.$get</Scope.prototype.$eval@http://code.angularjs.org/1.3.1/angular.js:14110:16
$RootScopeProvider/this.$get</Scope.prototype.$apply@http://code.angularjs.org/1.3.1/angular.js:14208:18
ngEventHandler/<@http://code.angularjs.org/1.3.1/angular.js:22553:17
createEventHandler/eventHandler@http://code.angularjs.org/1.3.1/angular.js:2979:9
" angular.js:11339

"after window open"

Tested on Firefox 33.1.1 in Windows 7 and OS X with Angular 1.3.1, but I've observed the same thing on older versions of both Firefox and Angular so it's not a regression. I used window.open to trigger timeout processing for the repro but I have reason to believe that other operations can do it too. I haven't seen this happen in Chrome or any other browser.

I don't know the formal spec of setTimeout well enough to guess whether this is a bug in Firefox or not, but in either case it seems like something that's worth guarding against in Angular.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions