javascript - Deferred chain crashing browser -


this small function should able open , close box. opening , closing needs take account css transitions, figured can use $.deferred.

here's relevant code:

function test(){    // these assigned deferred objects during transitions   this.opening = this.closing = false;    this.isopen = false;   this.x = $('<div />').appendto('body');   this.x.width(); }  test.prototype.open = function(){    // box opening: return opening deferred   if(this.opening)         return this.opening;    // box closing: chain   // supposed wait box close,   // open again    if(this.closing)     return this.closing.then((function(){       return this.open();     }).bind(this));    // box open, resolve   if(this.isopen)     return $.when();        console.log('opening');   this.opening = new $.deferred();   this.x.addclass('open');   settimeout((function(){     this.opening.resolve();     this.opening = false;     this.isopen = true;         }).bind(this), 1000);    return this.opening; }; 

the close() function open() in reverse.

the problem appears when try close box while it's being opened, or vice-versa. example:

var t = new test();  t.open(); // takes 1 second  // call close() after 0.05s settimeout(function(){   t.close(); }, 50); 

it appears there's stack overflow happening or that. know what's causing it?

the entire test code here, higher timeout value doesn't crash chrome.

i notices several issues code:

  • returning deferred objects instead of promises, can execute .then() on promises

  • overriding deferred variable bool value, using deferred.state() instead

this updated version of code:

function test(){   this.opening = this.closing = false;   this.isopen = false;   this.x = $('<div />').appendto('body');   this.x.width(); }  test.prototype.open = function(){   if(this.opening && this.opening.state() == 'pending')         return this.opening.promise();    if(this.closing && this.closing.state() == 'pending')     return this.closing.promise().then((function(){       return this.open();     }).bind(this));    if(this.isopen)     return $.when();        console.log('opening');   this.opening = new $.deferred();   this.x.addclass('open');   settimeout((function(){     this.isopen = true;         this.opening.resolve();   }).bind(this), 1000);    return this.opening.promise(); };  test.prototype.close = function(){   if(this.opening && this.opening.state() == 'pending') {     console.log('opening pending');     return this.opening.promise().then((function(){       console.log('opening resolved');       return this.close();     }).bind(this));   }    if(this.closing && this.closing.state() == 'pending'){         console.log('closing pending');     return this.closing.promise();   }    if(!this.isopen)     return $.when();        console.log('closing');   this.closing = new $.deferred();   this.x.removeclass('open');   settimeout((function(){     console.log('closing resolved');     this.closing.resolve();     this.isopen = false;   }).bind(this), 1000);    return this.closing.promise();   };  var t = new test();  t.open();  settimeout(function(){   t.close(); }, 15); 

the output:

"opening" "opening pending" "opening resolved" "closing" "closing resolved" 

Comments

Popular posts from this blog

c# - Binding a comma separated list to a List<int> in asp.net web api -

Delphi 7 and decode UTF-8 base64 -

html - Is there any way to exclude a single element from the style? (Bootstrap) -