如何避免由于太多ajax调用而导致浏览器内存不足错误

Posted

技术标签:

【中文标题】如何避免由于太多ajax调用而导致浏览器内存不足错误【英文标题】:How to avoid out of memory error in a browser due to too many ajax calls 【发布时间】:2014-04-15 14:36:06 【问题描述】:

我正在构建一个 Web 应用程序,它需要使用 jquery ajax 短格式一次进行大约 28000 次数据库调用。

它通过了大约 6000 个调用,但随后浏览器在浏览器控制台中给了我大约 20000 个以下错误(每个调用一个):

POST(我的数据库调用)net :: ERR_INSUFFICIENT_RESOURCES

有谁知道如何解决这个问题?也许要创建一个缓冲区或其他什么?

谢谢!

编辑1:添加一些代码:

好的,所以用户可以填写一些值(比如 GHI > 4500,宽高比介于 157.5 和 202.5 之间)

将进行以下调用:

loadAllData('ghi', 4500, findIdealPoints);

这个调用导致这个函数:

function loadAllData(type, above, callback)
var data = ;
$.post('php/getIdealData.php?action=get&type='+type+'&above='+above, data, callback);

在 PHP 中运行此查询:

 "SELECT  `GHI` ,  `lat` ,  `long` 
    FROM solar
    WHERE  `GHI` >'$_GET['above']' ORDER BY `lat`,`long`;";

以 JSON 格式返回数组中的大约 28880 条记录,并调用执行以下操作的回调方法:

function findIdealPoints(data)
var i = 0;
while (i < data.length)
    loadAspectWithinRange('aspect', data[i]['lat'], data[i]['long'], 10, compareWithAspect);
    i++;
     

运行这个 php 查询:

"SELECT `aspect`,
            `lat`, `long`, distance_in_km
            FROM (
                SELECT `aspect`, `lat`, `long`,r,
                (6378.10 * ACOS(COS(RADIANS(latpoint))
                * COS(RADIANS(`lat`))
                * COS(RADIANS(longpoint) - RADIANS(`long`))
                + SIN(RADIANS(latpoint))
                * SIN(RADIANS(`lat`)))) AS distance_in_km
            FROM aspect
            JOIN (
                SELECT  '$_GET['lat']'  AS latpoint, '$_GET['long']' AS longpoint, 10.0 AS r
            ) AS p
            WHERE `lat`
                BETWEEN latpoint  - (r / 111.045)
                AND latpoint  + (r / 111.045)
            AND `long`
                BETWEEN longpoint - (r / (111.045 * COS(RADIANS(latpoint))))
                AND longpoint + (r / (111.045 * COS(RADIANS(latpoint))))
            AND `aspect`
                BETWEEN '$_GET['lowA']' AND '$_GET['highA']'
            ) d
            WHERE distance_in_km <= r
            ORDER BY distance_in_km";

然后转到运行它的回调函数:

function compareWithAspect(data)
var idealPoints =[];
for (var i=0; i<data.length; i++)
            idealPoints.push(new google.maps.LatLng(data[i]['lat'], data[i]['long']));
        

        if (idealPoints.length > 1)
            makePolygon(idealPoints)
        

而 makePolygon 只是使用 Google Maps API 在地图上绘制。

我知道这很多而且看起来很复杂,如果有人能告诉我一个更好的方法,我会很高兴的!

再次感谢

【问题讨论】:

为什么需要打这么多电话?是不是可以加入他们,这样你就不会接到那么多电话了? 不可能,我正在构建一个太阳能规划应用程序,它必须使用某些参数检查地图上每个点的质量。所以我采用大参数并将其与第二个参数进行比较。例如,有 GHI 和坡向,我需要所有高于 4500 的 GHI,即大约 28000 条记录,然后我需要检查每条记录周围 10 公里的任何朝南的坡向并标记这些点。 听起来你真的不需要那么多电话。你能分享你的代码吗? 28k 条记录中的每条记录都获得了 10 公里左右的所有点? 添加了一些代码!谢谢! 【参考方案1】:

你可以这样做。

function findIdealPoints(data)
   var i = 0;
    while (i < data.length)
       loadAspectWithinRange('aspect', data[i]['lat'], data[i]['long'], 10,          
     compareWithAspect);
    i++;

不要为每次出现都进行 Ajax 调用,而是将数据对象发送给您的调用

 loadAspectWithinRange('aspect',data,10,compareWithAspect)

然后在 Ajax 请求中将对象数组发送到您的服务并检索所有对象的结果,而不是一个一个地检索。

$.ajax(
   url:"...",
   data:
       attr1:'aspect',
       points: data(here is the array retrieved from "getIdealData.php")
       attr2: 10
    ,
   success:function(data)
      compareWithAspect(data)
   
)

在服务器端处理中为getIdealData.php 点上的所有元素构建一个对象数组。

这会更好,而不是为每个元素做一个 Ajax

【讨论】:

非常感谢!这实际上应该比我以前做的更有效率。编辑:我会在尝试时将其标记为正确:) 实际上这对我来说行不通,因为如果我这样做,它只会画出一大堆不代表任何东西的连接线。每个点都需要分别到达多边形抽屉。但是,我认为我将采取不同的方法:我将同时进行调用并在 javascript 中进行距离检查/逻辑,而不是进行如此多的数据库调用。 如果您需要为 28800 次调用中的每一个绘制一个多边形,为什么不发送它们并以这种方式返回类似列表的列表,您可以将一个 LatLon 对象列表添加到第一个列表中第一个查询的结果以这种方式发送,您将拥有一个 List> 并且您将拥有至少按列表中每个多边形所需数据排序的数据。 我试过了,但是在使用较小的样本进行测试时,在服务器端运行它实际上会更慢。28800 是最大的情况。此外,由于需要花费大量时间,因此无法向潜在用户指示完成百分比。与需要 20 分钟才能完成相比,这将使它变得不那么可用..(我让它在 Firefox 上运行,它现在只在 Chrome 中崩溃)

以上是关于如何避免由于太多ajax调用而导致浏览器内存不足错误的主要内容,如果未能解决你的问题,请参考以下文章

如何避免由于内存不足导致的gcc崩溃

WPF 绘图效率的问题 如何速度快而且又避免卡顿

内存不足是啥原因

如何避免 Spark executor 丢失以及由于内存限制而导致纱线容器杀死它?

如何在 swift 中避免由于 AFNetworking 导致的内存泄漏

如何使用 Laravel 的块来避免内存不足?