如何在mousemove事件发出Ajax请求时保持JavaScript性能?

如何在mousemove事件发出Ajax请求时保持JavaScript性能?

问题描述:

$(document).bind('mousemove', function (e) 
{ 
    if (e.pageY > $(document).height() - 400) 
    { 
     $.ajax({ 
      url: '/Tweet/GetFiveUserTweets', 
      type: 'POST', 
      async: false, // preventing a lot of asynchronous requests    
      success: function (result) 
      { 
       // result 
      } 
     }); 
    } 
}); 

'async:false'挂起浏览器,直到请求完成,这并不好。如何在mousemove事件发出Ajax请求时保持JavaScript性能?

,当同时要求删除“async:false',十几作出,因为鼠标移动事件....

我不想挂浏览器。

我只想一次一个异步Ajax请求。

任何人都可以让我知道如何为这种情况做一个更好的编码?

编辑:

其实,当用户向下滚动的底部,我想送五条一个记录,并在底部添加他们。 www.twitter.com与鸣叫做到这一点....

什么有关:

$(window).bind('scroll', function() { 
if (nearBottomOfPage()) { 
    // load things here ... 
} 
}); 

我觉得它比鼠标移动好......是吗?

+1

请勿使用'async:false'。问题解决了:)无论如何你需要什么? – 2011-03-06 08:38:42

+0

为什么你想在这种情况下使用mousemove事件呢?开始处理触发器是不是有一个“不太可能发生”的事件? – 2011-03-06 08:39:18

+0

然后打十几个同时请求......如何处理它们......我一次只需要一个请求...... – 2011-03-06 08:41:40

使异步成立。

为避免多个同时发生的请求,请在启动请求之前检查变量,例如if(!active_check) {...},然后在启动时设置该变量active_check=true。请求完成后,再次将该变量设置为false/null。

if(!active_check) { 
    active_check=true; 
    //do request with callback to change active check when done 
} 

或使用你的代码...

$(document).bind('mousemove', function (e) 
{ 
    if ((e.pageY > $(document).height() - 400) && !active_check) 
    { 
     active_check = true; 
     $.ajax({ 
      url: '/Tweet/GetFiveUserTweets', 
      type: 'POST', 
      async: true, 
      success: function (result) 
      { 
       active_check = false; 
      } 
     }); 
    } 
}); 

也就是说,鼠标移动事件触发非常频繁。如果可以的话,你会想要使用别的东西。

+0

你还喜欢什么其他活动@Jonathan(除了mousemove)...你能不能让我知道... – 2011-03-06 08:57:18

+0

@Mazaz Khan没有使用空中警卫,没有重复事件是“安全”的。 – 2011-03-06 11:30:59

+0

@Muaz:你看过使用Infinte Scroll(http://www.infinite-scroll.com/infinite-scroll-jquery-plugin/)吗? – Mottie 2011-03-06 14:08:49

您是否尝试过使async = true?发生了什么?如果你得到“那么同时发出的十几个请求......如何处理它们”你的代码中谁/发出了这些请求?每个请求您将得到一个响应。

想一想:Ajax是拉技术。 Ajax推动会很棒,但它不存在。

因此,请使async:true始终为真,并了解您的代码如何制作数十个请求。

- pete

+0

async:true ......根据jquery规范默认是true,当我删除' async:false'....打了几十个同步请求...... – 2011-03-06 08:47:20

+0

@Muaz Khan因此,如果没有未完成的/正在进行的请求,只发送一个新的请求(也许考虑搜索这个 - 它eixsts - 和/或询问新帖子;基本方法包括计数器,队列或共享XHR对象等)。问题解决了。使用非异步*将永远不会在这里*。 – 2011-03-06 08:49:17

+0

@Muaz Khan参见http://api.jquery.com/jQuery.ajax/并注意暴露在'ajax'方法结果中的字段 - 这可能对测试空中状态有用吗? – 2011-03-06 08:53:02

这可能是一个真的不好的想法对鼠标移动事件的请求。

正如你提到的那样,这将导致数十个请求,超过任何平均服务器将采取/接受,无论如何在这种情况下。你应该重新考虑你的逻辑。

如果你需要这些请求在mousemove上被解雇,你应该扼杀它们。这可能看起来像:

$(function() { 
    var did_fire = false; 

    setInterval(function() { 
     if(did_fire) { 
      $.ajax({}); 
      did_fire = false; 
     } 
    }, 2000); 

    $(element).mouseover(function() { 
     did_fire = true; 
    }); 
}); 

这是一个非常简单的技术,以减少创建的请求到1/2000ms。

和往常一样,你可以为此疯狂并编写你自己的请求管理器(或者使用一个插件)来存储所有请求并按顺序触发它们。

+0

但即使用户不曾移动他的鼠标,这也会持续运行代码。 – 2011-03-06 10:26:01

+0

@Praveen:当然,但是认真每2秒这样一个超薄功能调用就没什么好担心的。即使在IE4上使用超级糟糕的电脑,这也不会影响任何东西。但是,您也可以在某个时间点开始/停止间隔。 – jAndy 2011-03-06 11:52:41

虽然你已经接受乔纳森Fingland的答案,它已得到了一些问题

  1. 通常Twitter或第三方应用程序需要JSONP数据类型(因为跨域请求它的一个约束)。在jQuery中,当dataType = JSONP时,如果发生任何错误(为了您可以使用插件),jQuery.ajax中指定的错误函数从不会被调用。这意味着如果在服务器active_check上发生任何错误,变量将永远保持true

  2. 假设用户在10秒内移动他的鼠标50秒和UR AJAX请求端成功,这意味着你还在制作4个或5个请求以这种方法

更好的解决方案

jQuery(function(){ 
    var delay=50; 
    var handler; 
    $(document).bind('mousemove', function(e) 
     { 
     if (e.pageY > $(document).height() - 400) 
      { 
       if(handler) 
       { 
       clearTimeout(handler); 
       } 
       else 
       { 
       handler= setTimeout(makeAjaxRequest,delay); 
       } 
      }    

     }); 
     function makeAjaxRequest() 
     { 
      $.ajax({ 
        url: '/Tweet/GetFiveUserTweets', 
        type: 'POST', 
        async: true, 
        success: function (result) 
        { 
         // do something 
        } 
       }); 
     } 
}); 
+1

虽然延迟是一个非常理想的补充,但我仍然会在成功回调中执行clearTimeout。这样做会将延迟从50更改为50加上ajax往返时间。这避免了对可能显着变化的ajax请求持续时间的任何假设。 – 2011-03-06 14:51:55