1

大家好!我在开发一个小 web 应用程序时遇到了问题。目标是从服务器上的声明文件夹中搜索文件中的特定单词。

为此,我使用 java.io.File 和 BufferReader 实现了递归算法。当我得到结果时,我使用我的 jsp 文件中的脚本将它们放在一个表中:

// Posting founded files in a table.
var files = response.getElementsByTagName("file");
// -> Creating the results table.
var table = "<table width=\"100%\">\n";

for (var i = 0, c = files.length; i < c; i++) {
// -> Building the number of apparence in each file.
var nb = files[i].getAttribute("nb");
var nbSentence = "";
if (nb == 1) { nbSentence = nb + " time in this file."; }
else { nbSentence = nb + " times in this file."; }

// Building and filling the table. 
if (i % 2 == 0) { table += "<tr class=\"pair\"><td><a href=" + files[i].firstChild.nodeValue + " target=\"_blank\" >"
                + files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; }
else { table += "<tr class=\"impair\"><td><a href=" + files[i].firstChild.nodeValue + " target=\"_blank\" >"
                + files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; }
}
table += "</table>\n";
// -> To end the procedure, we had the table to the right div.
document.getElementById("files").innerHTML = table;

我的问题是,使用此代码,所有结果都会一次性打印在目标表中。每次在算法中找到一个文件时,我都想一一看到结果。

我试图在 onreadystatestage 函数中将 readystate 更改为“3”:

xhr.onreadystatechange = function() {
if (xhr.readyState >= 3 && (xhr.status == 200 || xhr.status == 0)) {
    callback(xhr.responseXML);
    document.getElementById("loader").style.display = "none";
    document.getElementById("btn").value = "Search";
} else if (xhr.readyState < 3) {
    document.getElementById("loader").style.display = "inline";
    document.getElementById("btn").value = "Cancel";
}
};

但这并没有改变任何东西。有人有想法吗?我怎样才能一个一个地发送每个创建的文件?我必须在 servlet 类中这样做吗?

servlet 类中的 for 指令:

// If the input word name isn't empty, the algorithm is launched.
if (null != wordToSearch && !"".equals(wordToSearch))
{
lstFiles.clear();
searching(new File(contextPath), wordToSearch);

int n = lstFiles.size();
// Priting a message that indicate how many files have been found with the word to search.
emptyFieldMessage = n + " files has been found containing the word '" + wordToSearch + "'!";
output.append("<message>").append(emptyFieldMessage).append("</message>\n");
output.append("<lstFiles>\n");
// Then, files list with :
// - File path in "name" parameter,
// - Number of apparence of the word in "nb" parameter,
// - Formatted path as the value.
for(int i = 0; i < n; i++)
{
    output.append("<file name=\"" + lstFiles.get(i) + "\" nb=\"" + lstNbApparence.get(i) + "\" >").append(lstFilesPath.get(i)).append("</file>\n");
}
output.append("</lstFiles>\n");
}

为了更完整,整个脚本代码:

<script>
// Creating xhr variable.
var xhr = null;

// Creating the "Search" button function.
function request(callback) {

   // "Cancel" button case.
   if (xhr && xhr.readyState != 0)
   {
       xhr.abort();
   }
   // "Search" button case.
   else
   {
       // Calling the good function from external file.
       xhr = getXMLHttpRequest();

       // Callback and loading icon management.
       xhr.onreadystatechange = function() {
        if (xhr.readyState >= 3 && (xhr.status == 200 || xhr.status == 0)) {
            callback(xhr.responseXML);
            document.getElementById("loader").style.display = "none";
            document.getElementById("btn").value = "Search";
        } else if (xhr.readyState < 3) {
            document.getElementById("loader").style.display = "inline";
            document.getElementById("btn").value = "Cancel";
        }
      };

      // Calling the Servlet in charge of the recursion algorithm.
      var input = encodeURIComponent(document.getElementById("wordName").value);
      xhr.open("GET", "/webApp_Search_Merge/ActionServlet?wordName=" + input, true);
      xhr.send(null);
      }
}

// Creating the reponse function.
function readData(response) {

if (null != response)
{
    // Posting the message include in the XML file sending back by the Servlet.
    var message = response.getElementsByTagName("message");
    document.getElementById("message").innerHTML = message[0].firstChild.nodeValue;

    // Posting founded files in a table.
    var files = response.getElementsByTagName("file");
    // -> Creating the results table.
    var table = "<table width=\"100%\">\n";

    for (var i = 0, c = files.length; i < c; i++) {
        // -> Building the number of apparence in each file.
        var nb = files[i].getAttribute("nb");
        var nbSentence = "";
        if (nb == 1) { nbSentence = nb + " time in this file."; }
        else { nbSentence = nb + " times in this file."; }

        // Building and filling the table. 
        if (i % 2 == 0) { table += "<tr class=\"pair\"><td><a href=" + files[i].firstChild.nodeValue + " target=\"_blank\" >"
            + files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; }
        else { table += "<tr class=\"impair\"><td><a href=" + files[i].firstChild.nodeValue + " target=\"_blank\" >"
            + files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; }
    }
    table += "</table>\n";
    // -> To end the procedure, we had the table to the right div.
    document.getElementById("files").innerHTML = table;
}

}

提前感谢您的帮助,托马斯。

4

1 回答 1

0

我试图设置一个工作演示,但没有结果。我也在寻找为什么我找不到“睡眠”afunction并在 1000 毫秒后重新执行或任何你想要的方法。已经找到了答案,但我认为这并不是你所期望的:

睡眠功能将杀死浏览器,并可能杀死机器。Javascript 是单线程的,所以浏览器会在执行时阻塞,而循环本身只会占用大量 CPU。我听说过一些库实际上以异步方式正确睡眠,但我现在不记得名字了。


这是一个非常糟糕的主意。JavaScript 是单线程的,所以当 for 循环运行时,没有其他东西可以执行(js 计时器、浏览器事件,甚至大多数浏览器中的 UI)。尝试休眠 5 秒或更长时间,浏览器甚至会警告用户脚本运行缓慢。

只需使用 setTimeout。

还谈到了Native Javascript中的睡眠功能。看起来它就像一个框架或类似的东西。您可以下载并自行尝试。我不能说什么,因为我从未测试过,这只是我在互联网上找到的。

很抱歉告诉你坏消息。

于 2013-05-28T20:51:38.603 回答