{"action":"created","issue":{"url":"https://api.github.com/repos/Urigo/angular2-meteor/issues/140","repository_url":"https://api.github.com/repos/Urigo/angular2-meteor","labels_url":"https://api.github.com/repos/Urigo/angular2-meteor/issues/140/labels{/name}","comments_url":"https://api.github.com/repos/Urigo/angular2-meteor/issues/140/comments","events_url":"https://api.github.com/repos/Urigo/angular2-meteor/issues/140/events","html_url":"https://github.com/Urigo/angular2-meteor/issues/140","id":132440104,"number":140,"title":"autorun can cascade through zone.run()","user":{"login":"staeke","id":292397,"avatar_url":"https://avatars.githubusercontent.com/u/292397?v=3","gravatar_id":"","url":"https://api.github.com/users/staeke","html_url":"https://github.com/staeke","followers_url":"https://api.github.com/users/staeke/followers","following_url":"https://api.github.com/users/staeke/following{/other_user}","gists_url":"https://api.github.com/users/staeke/gists{/gist_id}","starred_url":"https://api.github.com/users/staeke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/staeke/subscriptions","organizations_url":"https://api.github.com/users/staeke/orgs","repos_url":"https://api.github.com/users/staeke/repos","events_url":"https://api.github.com/users/staeke/events{/privacy}","received_events_url":"https://api.github.com/users/staeke/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2016-02-09T14:53:29Z","updated_at":"2016-02-15T14:48:10Z","closed_at":null,"body":"Currently, calls like ```this.autorun(..., true)``` can cascade. By that I mean that the ```zone.run(...)``` call can synchronously lead to components being created, initialized and thus other autoruns to be run. But...this is depending on context and how/when the first autorun is run. The consequence if/when this happens is that Tracker is in a computation when the ```zone.run``` kicks off change detection. Further autorun calls will just add to the current computation, although all \"user code\" has already completed. I suggest a change to something like\r\n\r\n```typescript\r\nif (autoBind) {\r\n  hAutorun = Tracker.autorun(() => {\r\n            func();\r\n            Tracker.afterFlush(() => {\r\n                this._zone.run(() => {});\r\n            });\r\n        });\r\n}\r\n```\r\n\r\nCan make a PR if you agree"},"comment":{"url":"https://api.github.com/repos/Urigo/angular2-meteor/issues/comments/184236668","html_url":"https://github.com/Urigo/angular2-meteor/issues/140#issuecomment-184236668","issue_url":"https://api.github.com/repos/Urigo/angular2-meteor/issues/140","id":184236668,"user":{"login":"staeke","id":292397,"avatar_url":"https://avatars.githubusercontent.com/u/292397?v=3","gravatar_id":"","url":"https://api.github.com/users/staeke","html_url":"https://github.com/staeke","followers_url":"https://api.github.com/users/staeke/followers","following_url":"https://api.github.com/users/staeke/following{/other_user}","gists_url":"https://api.github.com/users/staeke/gists{/gist_id}","starred_url":"https://api.github.com/users/staeke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/staeke/subscriptions","organizations_url":"https://api.github.com/users/staeke/orgs","repos_url":"https://api.github.com/users/staeke/repos","events_url":"https://api.github.com/users/staeke/events{/privacy}","received_events_url":"https://api.github.com/users/staeke/received_events","type":"User","site_admin":false},"created_at":"2016-02-15T14:48:10Z","updated_at":"2016-02-15T14:48:10Z","body":"What I interpret your comment as is to do:\r\n\r\n```typescript\r\nfunc();\r\nif (!this._inZone) {\r\n  this._zone.run(() => {});\r\n}\r\n```\r\nWell, the way I see it we still need ```Tracker.afterFlush```. In zone or not, we don't want the extra ```zone.run(..)``` call to be run inside our autorun since we're not interested in tracking new dependencies within it, and new autoruns may happen as a result of ```zone.run()```, so it's simply not 100% safe.\r\n\r\nI tried my code with zone checking above. I was **never** in zone. I tried it again with the ```ApplicationRef```'s global zone. Then I'm in zone fairly often. And...we save quite many global ```ApplicationRef.tick``` and then change detection runs by not running that too often. But...we're also scheduling a lot of runs ourselves with a lot of consecutive ```Tracker.autoFlush``` So, in order to mitigate that, I'd rather propose something like\r\n\r\n```typescript\r\n// Static\r\nlet pendingTrackerFlush = false;\r\n...\r\nTracker.autorun(() => {\r\n    func();\r\n    if (!this._inZone && !pendingTrackerFlush) {\r\n        pendingTrackerFlush = true;\r\n        Tracker.afterFlush(() => {\r\n            this._zone.run(() => {\r\n                pendingTrackerFlush = false;\r\n            });\r\n        });\r\n    }\r\n});\r\n```\r\n\r\nNow, another problem is ```_inZone```. As we can't rely on our local zone for telling if we need ```ApplicationRef.tick()``` kicking off on zone end, we must look at the ```ApplicationRef```'s zone the way I see it. We could have it injected, but...then we're introducing another constructor parameter for a base class, which I think is unfortunate (see https://github.com/angular/angular/issues/6972). \r\n\r\nA middle ground might be to have the ```ApplicationRef``` constructor parameter there, but have it optional, since it's only for performance optimization reasons. "}}