我有一个大约18 000个元素的数组。我正在创建一个地图应用程序,我想在用户放大到某个级别时添加元素。
因此,当用户在9以下放大时,我会循环查找数组中的元素。
但是,通过元素循环需要一些时间,导致每次用户缩小并处于“级别9”时地图应用程序滞后。即使没有要添加的元素,所以瓶颈就是我想的循环。
我试图像它一样解决它:
function SearchElements(elementArr) {
var ret = new Promise(resolve => {
var arr = [];
for (var i in elementArr) {
var distanceFromCenter = getDistanceFromLatLonInKm(view.center.latitude, view.center.longitude, dynamicsEntities[i].pss_latitude, dynamicsEntities[i].pss_longitude);
var viewWidthInKm = getSceneWidthInKm(view, true);
if (distanceFromCenter > viewWidthInKm) continue;
arr.push(elementArr[i]);
}
resolve(arr);
});
return ret;
}
SearchElements(myElementsArray).Then(arr => {
// ...
});
但它仍然没有异步,这个方法在for循环运行时挂起。
答案 0 :(得分:2)
因为你仍然有一个紧密的循环遍历一个循环中的所有元素,你总会有响应问题
解决问题的一种方法是处理数据块
注意:我假设elementArr是一个javascript数组
function SearchElements(elementArr) {
var sliceLength = 100; // how many elements to work on at a time
var totalLength = elementArr.length;
var slices = ((totalLength + sliceLength - 1) / sliceLength) | 0; // integer
return Array.from({length:slices})
.reduce((promise, unused, outerIndex) =>
promise.then(results =>
Promise.resolve(elementArr.slice(outerIndex * sliceLength, sliceLength).map((item, innerIndex) => {
const i = outerIndex * sliceLength + innerIndex;
const distanceFromCenter = getDistanceFromLatLonInKm(view.center.latitude, view.center.longitude, dynamicsEntities[i].pss_latitude, dynamicsEntities[i].pss_longitude);
const viewWidthInKm = getSceneWidthInKm(view, true);
if (distanceFromCenter <= viewWidthInKm) {
return item; // this is like your `push`
}
// if distanceFromCenter > viewWidthInKm, return value will be `undefined`, filtered out later - this is like your `continue`
})).then(batch => results.concat(batch)) // concatenate to results
), Promise.resolve([]))
.then(results => results.filter(v => v !== undefined)); // filter out the "undefined"
}
使用:
SearchElements(yourDataArray).then(results => {
// all results available here
});
我在评论中提出的其他建议是Web Workers(我最初称之为工作线程,不知道我从哪里获得该术语) - 我对Web Workers不太熟悉,无法提供解决方案,{{3 }和https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers应该让你去
老实说,我认为这种
heavy
任务更适合Web Workers