【问题标题】:Setting up a Papa Parse progress bar with Web workers使用 Web Worker 设置 Papa Parse 进度条
【发布时间】:2016-08-11 23:58:35
【问题描述】:

我正在开发一个 CSV 解析 Web 应用程序,它收集数据然后使用它来绘制绘图图。到目前为止,它运行良好,但不幸的是,使用 papaparse 解析 CSV 文件需要一些时间,即使它们只有大约 3MB。

因此,当“爸爸”工作时,显示一些进展会很好。我可以选择便宜的隐藏 div,显示“我正在工作”,但更喜欢使用 <progress>

不幸的是,酒吧刚刚在爸爸完成工作后才更新。所以我尝试进入 webworkers 并使用工作文件来计算进度,并在 Papa Parses 配置中设置worker: true。仍然无济于事。

使用的配置(带步进功能)如下:

var papaConfig =
    {
        header: true,
        dynamicTyping: true,
        worker: true,
        step: function (row) {
            if (gotHeaders == false) {
                for (k in row.data[0]) {
                    if (k != "Time" && k != "Date" && k != " Time" && k != " ") {
                        header.push(k);
                        var obj = {};
                        obj.label = k;
                        obj.data = [];
                        flotData.push(obj);
                        gotHeaders = true;
                    }
                }
            }

            tempDate = row.data[0]["Date"];
            tempTime = row.data[0][" Time"];
            var tD = tempDate.split(".");
            var tT = tempTime.split(":");
            tT[0] = tT[0].replace(" ", "");
            dateTime = new Date(tD[2], tD[1] - 1, tD[0], tT[0], tT[1], tT[2]);

            var encoded = $.toJSON(row.data[0]);

            for (j = 0; j < header.length; j++) {
                var value = $.evalJSON(encoded)[header[j]]
                flotData[j].data.push([dateTime, value]);
            }

            w.postMessage({ state: row.meta.cursor, size: size });
        },
        complete: Done,
    }

主站点上的工作器配置:

var w = new Worker("js/workers.js");

w.onmessage = function (event) {
   $("#progBar").val(event.data);
};

而被调用的工人是:

onmessage = function(e) {
   var progress = e.data.state;
   var size = e.data.size;
   var newPercent = Math.round(progress / size * 100);

   postMessage(newPercent);
}

进度条更新了,但是是在解析完CSV文件并设置好数据后,所以调用了worker,但是解析后处理了答案。 Papa Parse 似乎也被称为工人。或者,如果在浏览器调试工具中检查调用,但网站仍然没有响应,直到所有数据都显示出来。

谁能指出我做错了什么,或者在哪里调整代码以获得工作进度条?我想这也会加深我对 web worker 的理解。

【问题讨论】:

    标签: javascript jquery csv web-worker papaparse


    【解决方案1】:

    您可以使用FileReader API 将文件作为文本读取,将字符串用“\n”分割,然后计算返回数组的长度。这就是你计算百分比的大小变量。

    然后您可以将 文件字符串 传递给 Papa(您不需要直接从文件中重新读取)并将行数(大小变量)传递给您的工作人员。 (我不熟悉工人,所以不确定你是如何做到的。)

    显然,这仅在 csv 文件中没有嵌入换行符时才有效(例如,字符串分布在带有换行符的多行中),因为这些将计为额外行,因此您不会达到 100% .不是致命错误,但如果它似乎总是在 100% 之前完成,用户可能会觉得奇怪。

    这里有一些示例代码可以给你一些想法。

    var size = 0;
    
    function loadFile(){
      var files = document.getElementById("file").files; //load file from file input
      var file = files[0];
      var reader = new FileReader();
      reader.readAsText(file);
      reader.onload = function(event){
        var csv = event.target.result; //the string version of your csv.
        var csvArray = csv.split("\n");
        size = csvArray.length;
        console.log(size); //returns the number of rows in your file.
        Papa.parse(csv, papaConfig); //Send the csv string to Papa for parsing.
      };
    }
    

    【讨论】:

      【解决方案2】:

      我之前没有在worker上使用过Papa Parse,但是玩了一会儿之后会弹出一些东西:

      • 似乎不希望您直接与工作人员互动
      • 它希望您要么想要整个最终结果,要么单个项目

      使用 web worker 使得提供 JS Fiddle 变得不可行,但这里有一些 HTML 演示了第二点:

      <html>
      <head>
          <script src="papaparse.js"></script>
      </head>
      
      <body>
      <div id="step">
      </div>
      
      <div id="result">
      </div>
      
      <script type="application/javascript">
          var papaConfig = {
              header: true,
              worker: true,
              step: function (row) {
                  var stepDiv = document.getElementById('step');
                  stepDiv.appendChild(document.createTextNode('Step received: ' + JSON.stringify(row)));
                  stepDiv.appendChild(document.createElement('hr'));
              },
              complete: function (result) {
                  var resultDiv = document.getElementById('result');
                  resultDiv.appendChild(document.createElement('hr'));
                  resultDiv.appendChild(document.createTextNode('Complete received: ' + JSON.stringify(result)))
                  resultDiv.appendChild(document.createElement('hr'));
              }
          };
      
          var data = 'Column 1,Column 2,Column 3,Column 4 \n\
      1-1,1-2,1-3,1-4 \n\
      2-1,2-2,2-3,2-4 \n\
      3-1,3-2,3-3,3-4 \n\
      4,5,6,7';
      
          Papa.parse(data, papaConfig);
      </script>
      </body>
      
      </html>
      

      如果您在本地运行此程序,您会看到 CSV 数据的四行中的每一行都有一行,但对 complete 回调的调用将获得 undefined。比如:

      Step received: {"data":[{"Column 1":"1-1",...
      Step received: {"data":[{"Column 1":"2-1",...
      Step received: {"data":[{"Column 1":"3-1",...
      Step received: {"data":[{"Column 1":"4","...
      Complete received: undefined
      

      但是,如果您删除或注释掉 step 函数,您将获得所有四个结果的一行:

      Complete received: {"data":[{"Column 1":"1-1",...
      

      还要注意,Papa Parse 使用流式概念来支持 step 回调,无论是否使用工作程序。这意味着您不会直接知道要解析多少项目,因此除非您可以单独找到项目的长度,否则无法计算完成百分比。

      【讨论】:

      • 是的,这很明显,但是,我尝试在这些步骤中更新 DOM。我的应用程序在运行 papaParse 之前冻结,稍后再恢复。提示:我使用 worker 设置为 true。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-06
      • 2021-11-13
      • 1970-01-01
      • 2022-09-27
      • 2018-05-29
      • 2018-09-20
      • 1970-01-01
      相关资源
      最近更新 更多