简体   繁体   English

forEach中的JavaScript回调

[英]Javascript callback inside a forEach

Javascript: 使用Javascript:

$(document).ready(function() {
    var systems = 'https://raw.githubusercontent.com/joeberthelot88/EVE-Online-Mapper/master/eveSystems.json?token=AWUj7mQ8T_6NBaRgIcz4Xz0KQd1SazMUks5ZjpeAwA%3D%3D';

    var constellations = [20000441, 20000442, 20000443, 20000444, 20000445, 20000446, 20000447];

    var arrayX = [];
    var arrayY = [];

    $.getJSON(systems, function(data) {

        data.forEach(function(systemData) {

            // Get data and build elements for each object found in constellations array
            if(constellations.indexOf(systemData.constellation_id) > -1) {

                // Simplify location coordinates
                var x = systemData.position.x / 100000000000000;
                var y = systemData.position.y / 100000000000000;

                // Push coordinates to arrays
                arrayX.push(x);
                arrayY.push(y);

                // Get the lowest coordinate values
                var offsetX = Math.min.apply(Math, arrayX);
                var offsetY = Math.min.apply(Math, arrayY);

                // Set pixel offsets to center in the viewport
                var coordX = x + offsetX;
                var coordY = y + offsetY;

                // Build SVG elements
                var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                svg.setAttribute('id', systemData.name);
                svg.setAttribute('title', systemData.name);
                svg.setAttribute('class', 'system');
                svg.setAttribute('constellation-id', systemData.constellation_id);
                svg.setAttribute('style', 'margin-top:'+coordY+'px;margin-left:'+coordX+'px');
                svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
                document.getElementById('container').appendChild(svg);
            } else {

            }
        });       
    });

    $(this.body).panzoom();
});

What this does: 这是做什么的:

  • Loops through a JSON object 遍历JSON对象
  • For each object, it looks for matches where the object contains the constellation_id 对于每个对象,它将在对象包含constellation_id的位置查找匹配项
  • If a match is found, it pushes the coordinates to an array and then the lowest number from each array gets stored as a variable 如果找到匹配项,则将坐标推送到一个数组,然后将每个数组中的最低编号存储为变量
  • During each loop, an SVG element is created 在每个循环中,都会创建一个SVG元素

Issue: 问题:

During creation of the SVG elements, I'm setting CSS margins with the coordX and coordY variables. 在创建SVG元素期间,我使用coordXcoordY变量设置CSS边距。 Instead, I need to swap those variables out with the new offsetX and offsetY ones, however this doesn't work because the offsetX and offsetY variables aren't at their final state due the arrayX and arrayY arrays still being built. 相反,我需要用新的offsetXoffsetY交换那些变量,但是这不起作用,因为因为arrayX和arrayY数组仍在构建中,所以offsetX和offsetY变量没有处于最终状态。

Basically, I need to build the offsetX and offsetY variables and THEN run the SVG creation. 基本上,我需要构建offsetX和offsetY变量,然后运行SVG创建。

This iteration can be split into two loops, first one is to build up all necessary for rendering data, and then the svg rendering loop itself. 该迭代可以分为两个循环,第一个循环是构建渲染数据所需的所有循环,然后是svg渲染循环本身。 Such split goes well along with idiomatic separation of rendering and state update that could be found in Flux / React, which might make it easier later to switch to them or similar frameworks. 这种拆分与Flux / React中常见的呈现和状态更新分离相得益彰,这可能使以后更容易切换到它们或类似框架。

Bonus points, if you can avoid forEach and use functions without side effects. 奖励积分,如果可以避免forEach并使用没有副作用的功能。 I would recommend immutable.js , as it provides many useful functional-style utilities and provides immutable data structures, and equality check (and use as a key) for containers (Lists, Maps, etc). 我会推荐immutable.js ,因为它提供了许多有用的功能样式实用程序,并提供了不变的数据结构,以及对容器(列表,地图等)的相等性检查(并用作键)。

Also, on a side note, I would recommend to switch to let and const syntax and use arrow functions. 另外,我建议您切换到letconst语法并使用箭头功能。

You could write the function like this, making use of Array#filter , Array#map , a Set , spread syntax, arrow functions, and more of jQuery for the DOM manipulation: 您可以这样编写函数,利用Array#filterArray#mapSet ,传播语法,箭头函数以及更多jQuery进行DOM操作:

$(function() {
    const systems = 'https://raw.githubusercontent.com/joeberthelot88/EVE-Online-Mapper/master/eveSystems.json?token=AWUj7mQ8T_6NBaRgIcz4Xz0KQd1SazMUks5ZjpeAwA%3D%3D';
    // Use a Set for faster look-up
    const constellations = new Set([20000441, 20000442, 20000443, 20000444, 20000445, 20000446, 20000447]);

    $.getJSON(systems, function(data) {
        data = data.filter(systemData => constellations.has(systemData.constellation_id));
        // Collect the coordinate values
        const arrayX = data.map(systemData => systemData.position.x / 100000000000000);
        const arrayY = data.map(systemData => systemData.position.y / 100000000000000);
        // Get least coordinate values
        const offsetX = Math.min(...arrayX);
        const offsetY = Math.min(...arrayY);
        $('#container').append( // Append array of elements in one go 
            data.map((systemData, i) => {
                // Set pixel offsets to center in the viewport
                const coordX = arrayX[i] + offsetX;
                const coordY = arrayY[i] + offsetY;
                // Build SVG elements
                const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
                return $(svg).attr({
                    id: systemData.name,
                    title: systemData.name,
                    "constellation-id": systemData.constellation_id,
                    "class": "system"
                }).css({ 
                    marginTop: coordY, 
                    marginLeft: coordX 
                });
            })
        );
    });

    $(this.body).panzoom();
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM