【问题标题】:jQuery function $.html() does not wait for other lines of code to finishjQuery 函数 $.html() 不等待其他代码行完成
【发布时间】:2021-08-04 01:30:18
【问题描述】:

我正在尝试从另一个文件中读取数据并在 HTML(更准确地说是 x3d)中使用这些数据。

为此,我使用 $.getJSON 读取数据,并使用$("div").html( "*html code*" ) 使用 html 代码中的变量在网站中显示数据。

问题是在$.getJSON读取数据之前执行了*$("div").html( "html code" )*

这是我的代码:

<html> 
    <head> 
        <title>Superficie soja 63</title>           
        <script type='text/javascript' src='http://www.x3dom.org/download/x3dom.js'> </script> 
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <link rel='stylesheet' type='text/css' href='http://www.x3dom.org/download/x3dom.css'></link> 
        
    </head> 

    <body> 
        <h1>Superficie soja 63</h1> 
        
        <div></div>
        <script>
            var a = [];
            var b = [];
            var c = [];
            var tria = [];
            var trib = [];
            var tric = [];
            var str = "";
            var str_tri = "";

            $.getJSON("dados_teste.json", function(data) {
                for(var cont in data.pontos){
                        a.push(data.pontos[cont].x);
                        b.push(data.pontos[cont].y);
                        c.push(data.pontos[cont].z);

                        str += (`${a[cont]} ${b[cont]} ${c[cont]}, `);
                }
                str = str.slice(0, -2);
            });

            $.getJSON("tri_teste.json", function(data) {
                for(var cont in data.triangulos){
                    tria.push(data.triangulos[cont].tri_a);
                    trib.push(data.triangulos[cont].tri_b);
                    tric.push(data.triangulos[cont].tri_c);

                    str_tri += (`${tria[cont]} ${trib[cont]} ${tric[cont]}, `);
                }
                str_tri = str_tri.slice(0, -2);
            });

        setTimeout(() => {  console.log(str); }, 1000);
        setTimeout(() => {  console.log(str_tri); }, 2000);

        $("div").html( ` 

            <x3d width='1000px' height='1000px'> 
                <scene> 
                    <shape> 
                        <appearance>
                            <ImageTexture 
                            url='https://thumbs.dreamstime.com/b/macro-soybean-food-texture-background-top-view-96368287.jpg'/>
                        <TextureTransform
                            translation='0 0'
                            rotation='0'
                            repeats='true'
                            repeatt='true'
                            scale='80 80'/>
                        </appearance>
                        
                        <IndexedTriangleSet 
                            ccw='true' 
                            colorPerVertex='true' 
                            index='${str_tri}'
                            normalPerVertex='true' 
                            solid='false'
                            containerField='geometry'>
                            <Coordinate id="teste"
                                point='${str}'/>
                            <Viewpoint
                                position='0 0 10'
                                orientation=''
                                description='camera'/>
                        </IndexedTriangleSet>
                    </shape> 
                </scene> 
            </x3d> ` )

    </script>

    </body> 
</html>

我已经尝试使用setTimeout()delay()来解决这个问题,但是看起来$.html()函数忽略了其他函数,总是先执行。

如果我只是将数据直接分配给变量,它就可以工作。问题是我需要读取一个 JSON 文件来获取数据。

我该如何解决这个问题?

编辑: 我刚刚发现只有当我在 HTML 中使用 X3D 时才会出现这个问题。 对于普通的 HTML,$.html() 可以正常工作。但是对于 X3D,函数 $.html() 不能正常运行。所以我还在想办法解决这个问题。

【问题讨论】:

标签: javascript html jquery x3d


【解决方案1】:

我尝试使用 javascript 以多种不同方式使这段代码工作,并发现问题出在 X3D 上。到目前为止发布的所有答案都是有道理的,但是当 HTML 代码中包含 X3D 时,它们就不起作用了。

所以我决定改用 PHP,现在它可以工作了!

<html> 
    <head> 
        <title>Superficie soja 63</title>           
        <script type='text/javascript' src='http://www.x3dom.org/download/x3dom.js'> </script> 
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <link rel='stylesheet' type='text/css' href='http://www.x3dom.org/download/x3dom.css'></link> 
        
    </head> 

    <body> 
        <h1>Superficie soja 63</h1> 

        <?php
            $path = "dados_teste.json";
            $file = fopen($path, "r");
            $data="";
            while(!feof($file)){
                $data .= fread($file, filesize($path));
            }
            fclose($file);
            $data= json_decode($data, true);
            $str="";
            for($cont=0; $cont < count($data["pontos"]); $cont++){
                if($cont < count($data["pontos"])-1)
                    $str .= ($data["pontos"][$cont]["x"] . " " . $data["pontos"][$cont]["y"] . " " . $data["pontos"][$cont]["z"] . ", " );
                else
                    $str .= ($data["pontos"][$cont]["x"] . " " . $data["pontos"][$cont]["y"] . " " . $data["pontos"][$cont]["z"] );
            }
            
            $path = "tri_teste.json";
            $file = fopen($path, "r");
            $data="";
            while(!feof($file)){
                $data .= fread($file, filesize($path));
            }
            fclose($file);
            $data= json_decode($data, true);
            $str_tri="";
            for($cont=0; $cont < count($data["triangulos"]); $cont++){
                if($cont < count($data["triangulos"])-1)
                    $str_tri .= ($data["triangulos"][$cont]["tri_a"] . " " . $data["triangulos"][$cont]["tri_b"] . " " . $data["triangulos"][$cont]["tri_c"] . ", " );
                else
                    $str_tri .= ($data["triangulos"][$cont]["tri_a"] . " " . $data["triangulos"][$cont]["tri_b"] . " " . $data["triangulos"][$cont]["tri_c"] );
            }

            echo "
            <x3d width='1000px' height='1000px'> 
                <scene> 
                    <shape> 
                        <appearance>
                            <ImageTexture 
                            url='https://thumbs.dreamstime.com/b/macro-soybean-food-texture-background-top-view-96368287.jpg'/>
                        <TextureTransform
                            translation='0 0'
                            rotation='0'
                            repeats='true'
                            repeatt='true'
                            scale='80 80'/>
                        </appearance>
                        
                        <IndexedTriangleSet 
                            ccw='true' 
                            colorPerVertex='true' 
                            index='${str_tri}'
                            normalPerVertex='true' 
                            solid='false'
                            containerField='geometry'>
                            <Coordinate
                                point='${str}'/>
                            <Viewpoint
                                position='0 0 10'
                                orientation=''
                                description='camera'/>
                        </IndexedTriangleSet>
                    </shape> 
                </scene> 
            </x3d>
            ";
        ?>

    </body> 
</html>

我的结论是:如果您正在使用 X3D,最好使用后端编程语言。

【讨论】:

    【解决方案2】:

    我不是 jQuery 专家,但是通过快速查找,我认为您应该尝试 getJSON 之后的 .then() 函数,然后将其余代码写在 then 括号内。在this question中使用了一个示例

    此外,您可以使用 this link 中指定的 .done() 来代替 .then()(您必须向下滚动一点才能看到 .done() 示例)

    另一种选择是将您的 $("div").html() 添加到 getJson 回调函数中,如下所示:

     $.getJSON("dados_teste.json", function(data) {
         //your current code
         //you $("div").html() code
     }
    

    如果这个答案有帮助,请告诉我:)

    【讨论】:

      【解决方案3】:

      尝试将一个任务的执行时间与另一个任务的开始相匹配称为race condition,应该避免。而是在收到变量后致电您的.html()。因为您有 2 个独立的依赖进程创建变量,所以您可以在 makeDiv() 函数中检查它们。

      var str, str_tri
       $.getJSON("dados_teste.json", function(data) {
                     ...
                      str = str.slice(0, -2);
                      makeDiv();
                  });
       $.getJSON("tri_teste.json", function(data) {
                     ...
                      str_tri = str_tri.slice(0, -2);
                      makeDiv();
                  });
      
      
      function makeDiv() {
       if (!str || !str_tri || str =='' || str_tri == '') return;
       $("div").html( `......`);
      }
      

      【讨论】:

      • 好吧,我想我说得太早了。我的代码没有考虑到您有 2 个变量正在等待,因此值得一票否决。我修改了答案,如果有帮助,请告诉我。
      • @LucasVoelcker - 有帮助吗?
      • 我意识到您的解决方案适用于普通 HTML,就像这里回答的其他解决方案也有意义一样。问题是X3D。当我在 HTML 中使用 X3D 时,$.html() 无法正常工作。所以我想也许 javascript 不是与 X3D 一起使用的最佳语言。我现在用 PHP 进行了测试,它成功了!
      猜你喜欢
      • 2020-12-16
      • 1970-01-01
      • 2011-04-10
      • 1970-01-01
      • 1970-01-01
      • 2021-01-07
      • 2019-11-25
      • 2020-10-11
      • 1970-01-01
      相关资源
      最近更新 更多