JavaScript-如何检查命令执行是否完成?

时间:2019-05-31 09:12:44

标签: javascript arrays function

我想制作一个3D矩阵,并用文本文件中的值填充它,然后制作一个尺寸为180 * 90的网格,并根据我的矩阵中的值对其进行着色,

例如:蓝色表示负值,红色表示正值,白色表示零值。

我想将我从文本文件中读取的内容存储在3D矩阵中。

但是当我执行我的html文件并使用时,我遇到了问题  console.log(myMatrix)会显示undefined,当我在控制台中复制粘贴for-loop时,

例如  console.log(myMatrix[0][0][4])向我显示了正确的答案,即90

所以我想可能是问题与 javaScript 有关,因为 js 读取了所有代码,当我尝试console.log(myMatrix[0][0][4])时,它显示了undefined因为读取文件并存储在数组中还没有完成,但是当我使用控制台命令(因为它位于RAM中)时,我可以看到正确的答案。

因此,我决定检查是否已读取文件并将其存储在完整的数组中,然后执行我的for-loop将值从数组存储到myMatrix。但是我不知道该怎么办?

我尝试使用setTimeout,但是我认为也许我系统中的执行时间不同于其他系统或网络。我也想使用Callback函数,但是我什么都没做。我希望你能帮助我。

这是我的代码:

<!DOCTYPE html>
<html>
    <head>
        <script src="https://d3js.org/d3.v5.min.js"></script>
    </head>
    <body>

        <div id="grid"></div>
        <script>
        //creat 1670 numbers of matrices with size of 180*90
                var myMatrix = new Array(1670)
                for (var i=0; i<1670; i++){
                    myMatrix[i] = twodmatrix()
                }

                function twodmatrix(){
                    var myMat = new Array(180)
                    for (var i=0; i<180; i++){
                        myMat[i] = new Array(90)
                    }
                    return(myMat)
                } 


                var myGrid = new Array(1670)
                for (var i=0; i<1670; i++){
                    myGrid[i] = twodmatrix()}




                var array = new Array()

                    xmlhttp = new XMLHttpRequest();
                    xmlhttp.open("GET", "tempanomaly_new.txt", true);
                    xmlhttp.send();
                    xmlhttp.onreadystatechange=function() {
                        if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                            parse(xmlhttp.responseText);
                        }
                    }
                function parse (text) {
                     array = text.split(",");
                     return array
                    //Do something

                }


                function treeDmatrix(){ 
                var n=0;            
                for(var i=0;i<1670;i++){
                    for(var j=0;j<180;j++){
                        for(var k=0; k<90; k++){myMatrix[i][j][k]= array[n];
                                                n +=1;}}}

                }                           

                /*var mycolor;

                for(var i=0; i<array.length; i++){
                    if (array[i] == 0){ function white(){  mycolor = d3.scalelinear().domain([1,5]).range(["white"])}}
                    else if (array[i] > 0 ){ function red(){ mycolor = d3.scalelinear().domain([1,5]).range(["red"])}}
                    else if (array[i] < 0 ){function blue(){ mycolor = d3.scalelinear().domain([1,5]).range(["blue"])}}                 
                }       





                /* Start make a grid and color it */
                /*
                const BLOCK_SIZE = 30;
                const BLOCK_SPACE = 5;
                const ROW_SIZE = 90;
                const COL_SIZE = 180;



                gridData = new Array(COL_SIZE);
                for (var i = 0; i < COL_SIZE; i++) {
                    gridData[i] = new Array(ROW_SIZE);
                    for (var j = 0; j < ROW_SIZE; j++) {
                        gridData[i][j] = {
                            x: (i + 1) * BLOCK_SIZE + BLOCK_SPACE,
                            y: (j + 1) * BLOCK_SIZE + BLOCK_SPACE,
                            size: BLOCK_SIZE,
                            }}}


    var grid = d3.select("#grid")
    .append("svg")
    .attr("width", "100%")
    .attr("height", "100%")
    .style("color", "#b2b2b2");

    var row = grid.selectAll(".row")
    .data(gridData)
    .enter().append("g")
    .attr("class", "row");

    var column = row.selectAll(".square")
    .data(function(data) { return data; })
    .enter()
    .append("rect")
    .attr("class", "square")
    .attr("x", function(data) { return data.x; })
    .attr("y", function(data) { return data.y; })
    .attr("width", function(data) { return data.size; })
    .attr("height", function(data) { return data.size; })
    .style("stroke", "#222")
    .style("fill", function(data) { return mycolor(data)});*/
        </script>
    </body> 
</html> 

2 个答案:

答案 0 :(得分:1)

onreadystatechange是一个异步函数,因此很可能只有在运行所有脚本之后才调用它。因此,您必须等到调用parse函数之后,再继续处理数据。我建议您将所有代码移至parse内并进行检查。如果您确实想以正确的方式进行操作,请阅读有关Promise的信息。

答案 1 :(得分:1)

XMLHTTPRequest是异步的。这意味着JS只会启动数据请求并继续处理其余代码。当请求的数据到达时(为简单起见,我会说),它将触发onreadystatechange函数。

现在,这是您应该填充数组并开始处理它的时刻。将循环放入名为buildMatrix的函数中,并在数据到达后执行该函数。

xmlhttp.onreadystatechange=function() {
                        if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                            var d = parse(xmlhttp.responseText);
                            buildMatrix(d);
                        }
                    }

所有这些操作结束后,将矩阵记录到控制台。因此,要在代码中执行的最后一行是

buildMatrix(d)
console.log(myMatrix)