이것은 상자를 열고 닫을 수 있어야하는 작은 기능입니다. 열기 및 닫기는 일부 CSS 전환을 고려해야하므로 $.Deferred
.
다음은 관련 코드입니다.
function Test(){
// these are 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 is already opening: return opening deferred
if(this.opening)
return this.opening;
// box is closing: this is the chain
// that is supposed to wait for the box to close,
// then open it again
if(this.closing)
return this.closing.then((function(){
return this.open();
}).bind(this));
// box is already open, resolve immediately
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;
};
close () 함수는 반대로 open ()입니다.
상자를 여는 동안 상자를 닫으려고 할 때 또는 그 반대의 경우 문제가 나타납니다. 예를 들면 :
var t = new Test();
t.open(); // takes 1 second
// call close() after 0.05s
setTimeout(function(){
t.close();
}, 50);
스택 오버플로가 발생하는 것 같습니다. 누구든지 그 원인을 알고 있습니까?
전체 테스트 코드가 여기 에 있지만 시간 제한 값이 더 높기 때문에 Chrome이 충돌하지 않습니다.
코드에 몇 가지 문제가 있습니다.
promise 대신 지연된 객체를 반환 하면 promise에서만 .then ()을 실행할 수 있습니다.
지연된 변수를 bool 값으로 재정의하고 대신 deferred.state ()를 사용하고 있습니다.
다음은 코드의 업데이트 된 버전입니다.
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 is pending');
return this.opening.promise().then((function(){
console.log('opening is resolved');
return this.close();
}).bind(this));
}
if(this.closing && this.closing.state() == 'pending'){
console.log('closing is 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);
출력 :
"opening"
"opening is pending"
"opening is resolved"
"closing"
"closing resolved"
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다