Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 延迟链崩溃浏览器_Javascript_Jquery_Promise_Stack Overflow_Jquery Deferred - Fatal编程技术网

Javascript 延迟链崩溃浏览器

Javascript 延迟链崩溃浏览器,javascript,jquery,promise,stack-overflow,jquery-deferred,Javascript,Jquery,Promise,Stack Overflow,Jquery Deferred,这是一个小功能,应该能够打开和关闭一个盒子。打开和关闭需要考虑一些CSS转换,所以我想我可以使用$.Deferred 以下是相关代码: function Test(){ // these are assigned Deferred objects during transitions this.opening = this.closing = false; this.isOpen = false; this.x = $('<div />').appendTo('b

这是一个小功能,应该能够打开和关闭一个盒子。打开和关闭需要考虑一些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;
};
似乎发生了堆栈溢出之类的情况。有人知道是什么引起的吗


整个测试代码都是,但超时值更高,因此不会使Chrome崩溃。

我注意到您的代码有几个问题:

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);
  • 返回延迟对象而不是,您只能对承诺执行.then()

  • 用bool值重写延迟变量,我使用

这是您的代码的更新版本:

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);

我注意到您的代码有几个问题:

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);
  • 返回延迟对象而不是,您只能对承诺执行.then()

  • 用bool值重写延迟变量,我使用

这是您的代码的更新版本:

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);

这里有一个很小的时间问题。当您在
.closing
承诺之后链接打开,或在
.opening
承诺之后链接关闭时,将在删除承诺之前执行这些回调:

问题是jQuery确实是从
解析
中同步执行的,因此当
承诺仍然存在时,将调用关闭后链接的“重试”
this.open()
,并一次又一次地链接自身

你应该可以通过这样做来避免这种情况

var def = this.opening;
this.opening = false;
this.isOpen = true;
def.resolve(); // trigger those who are waiting to immediately close it again

这里有一个很小的时间问题。当您在
.closing
承诺之后链接打开,或在
.opening
承诺之后链接关闭时,将在删除承诺之前执行这些回调:

问题是jQuery确实是从
解析
中同步执行的,因此当
承诺仍然存在时,将调用关闭后链接的“重试”
this.open()
,并一次又一次地链接自身

你应该可以通过这样做来避免这种情况

var def = this.opening;
this.opening = false;
this.isOpen = true;
def.resolve(); // trigger those who are waiting to immediately close it again

我无法击败Bergi对“堆栈溢出”问题的解释,但是我忍不住认为您最好不要尝试管理自己的动画队列,这既困难又不必要

通过明智地使用jQuery的内置和方法,您可以使CSS转换的行为完全像jQuery动画一样-集成到元素的标准“fx”队列中,并由
.promise()
方法返回其承诺

function Test() {
    this.x = $('<div/>').appendTo('body');
    this.x.width();
    this.transitionEndString = 'webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend'; // cross-browser "transitionend" event names.
}

Test.prototype.open = function() {
    var that = this,
        x = this.x;
    x.queue('fx', function(next) {
        if(!x.hasClass('open')) {
            x.addClass('open').one(that.transitionEndString, next);
        } else {
            x.dequeue();
        }
    });
    return x.promise();
};
Test.prototype.close = function() {
    var that = this,
        x = this.x;
    x.queue('fx', function(next) {
        if(x.hasClass('open')) {
            x.removeClass('open').one(that.transitionEndString, next);
        } else {
            x.dequeue();
        }
    });
    return x.promise();
};
功能测试(){
this.x=$('').appendTo('body');
这个.x.宽度();
this.transitionEndString='WebKittTransitionEnd otTransitionEnd otTransitionEnd msTransitionEnd transitionend transitionend';//跨浏览器的“transitionend”事件名称。
}
Test.prototype.open=函数(){
var=这个,
x=这个.x;
x、 队列('fx',函数(下一个){
如果(!x.hasClass('open')){
x、 addClass('open').one(that.transitionEndString,next);
}否则{
x、 出列();
}
});
返回x.promise();
};
Test.prototype.close=函数(){
var=这个,
x=这个.x;
x、 队列('fx',函数(下一个){
if(x.hasClass('open')){
x、 removeClass('open').one(that.transitionEndString,next);
}否则{
x、 出列();
}
});
返回x.promise();
};
else{x.dequeue();}
子句是在未调用转换时强制承诺响应所必需的


我无法击败Bergi对“堆栈溢出”问题的解释,但是我忍不住认为您最好不要尝试管理自己的动画队列,这既困难又不必要

通过明智地使用jQuery的内置和方法,您可以使CSS转换的行为完全像jQuery动画一样-集成到元素的标准“fx”队列中,并由
.promise()
方法返回其承诺

function Test() {
    this.x = $('<div/>').appendTo('body');
    this.x.width();
    this.transitionEndString = 'webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend'; // cross-browser "transitionend" event names.
}

Test.prototype.open = function() {
    var that = this,
        x = this.x;
    x.queue('fx', function(next) {
        if(!x.hasClass('open')) {
            x.addClass('open').one(that.transitionEndString, next);
        } else {
            x.dequeue();
        }
    });
    return x.promise();
};
Test.prototype.close = function() {
    var that = this,
        x = this.x;
    x.queue('fx', function(next) {
        if(x.hasClass('open')) {
            x.removeClass('open').one(that.transitionEndString, next);
        } else {
            x.dequeue();
        }
    });
    return x.promise();
};
功能测试(){
this.x=$('').appendTo('body');
这个.x.宽度();
this.transitionEndString='WebKittTransitionEnd otTransitionEnd otTransitionEnd msTransitionEnd transitionend transitionend';//跨浏览器的“transitionend”事件名称。
}
Test.prototype.open=函数(){
var=这个,
x=这个.x;
x、 队列('fx',函数(下一个){
如果(!x.hasClass('open')){
x、 addClass('open').one(that.transitionEndString,next);
}否则{
x、 出列();
}
});
返回x.promise();
};
Test.prototype.close=函数(){
var=这个,
x=这个.x;
x、 队列('fx',函数(下一个){
if(x.hasClass('open')){
x、 removeClass('open').one(that.transitionEndString,next);
}否则{
x、 出列();
}
});
返回x.promise();
};
else{x.dequeue();}
子句是在未调用转换时强制承诺响应所必需的


谢谢!刚刚意识到,如果我同时使用两种解决方案,我可以使用一个延迟解决方案,谢谢!我刚刚意识到,如果我将这两种解决方案结合起来,我可以使用一个延迟解决方案。问题是,我真正的代码有点复杂。除了CSS转换之外,box还必须考虑插件生成的承诺,这些插件将自己与box中的元素挂钩/解钩。但您的解决方案绝对是最优雅的,我将尝试使其适应我的代码。谢谢听起来您应该在代码中执行调用
.open()
.close()
的所有其他操作,这些操作仍然是低级的承诺返回方法。至少,这是你应该追求的目标。问题是我真正的代码有点复杂。除了CSS转换之外,该框还必须考虑挂钩/取消挂钩的插件产生的承诺