I recently encountered a bug with Ember.js. Basically when I click the browser back button in Firefox, Ember.js executes the code in wrong order. The code in willTransition
callback right after the line alert("...");
is executed after model
callback, which should normally be executed right after alert("...");
is returned.
The code is:
App = Ember.Application.create();
App.Router.reopen({
location: 'history'
});
App.Router.map(function() {
this.route('foo');
});
App.IndexRoute = Ember.Route.extend({
actions:{
willTransition: function(transition){
console.log('start IndexRoute#willTransition');
alert('See console logs');
console.log('end IndexRoute#willTransition');
}
}
});
App.FooRoute = Ember.Route.extend({
model: function() {
console.log('start FooRoute#model');
return [];
}
});
An instruction on how to reproduce the bug can be found here: https://github.com/goooooouwa/location/blob/master/README.md
See this bug in action with Firefox( version 12+ on OS X, version 7+ on Windows) on JSBin: http://emberjs.jsbin.com/tefoka/
The root cause of this behaviour is this Firefox bug.
PopStateEvent
, and Ember then handles this event with onUpdateURL()
callbackthis._doURLTransition('handleURL', url);
run.backburner.schedule('actions', function(){...})
, since no runloop is created, an autorun will be created by calling Backburner.createAutoRun()
:function createAutorun(backburner) {
backburner.begin();
backburner._autorun = global.setTimeout(function() {
backburner._autorun = null;
backburner.end();
});
}
before the auto-created runloop ends, the following code is executed:
willTransition: function(transition){
console.log('-------------- 1. start IndexRoute#willTransition -------------- ');
alert('See console logs');
console.log('-------------- 2. end IndexRoute#willTransition -------------- ');
}
when the runloop ends, the flush process begins, and the following code is executed:
model: function() {
console.log('-------------- 3. start FooRoute#model -------------- ');
return [];
}
The above code is essencailly the same as:
console.log('processing: task #1');
setTimeout(function(){
console.log('processing: task #3');
},0);
alert('See console logs');
console.log('processing: task #2');
The above code runs wrongly with the Firefox bug, which causes the Ember behaviour in question.