使用setTimeout可以在进行数据输入时推迟时间密集型处理

Use setTimeout to postpone time intensive processing while data entry taking place

本文关键字:输入 推迟 时间 处理 密集型 数据 setTimeout 使用      更新时间:2024-05-24

我有一个文本区域,用户在其中键入一些数据。我需要在数据更改时读取这些数据并进行处理,处理非常耗时。

我有textarea事件:changekeyup剪切粘贴输入调用函数triggerProcess()。

如果只在文本区域中键入一个字符(或只删除一个字符),则需要调用triggerProcess()。

如果键入了一个由几个字符组成的单词,那么如果为该单词中的每个字符调用triggerProcess(),则整个系统将陷入停顿。即使系统没有陷入停顿,为每个字符调用triggerProcess()也是毫无意义的,因为需要处理的是整个单词加上整个内容。但是,可能需要处理单个字符,如"I"或数字。

如果打字员正在键入一个单词或句子(如果打字手很快),我想推迟处理,但一旦他们暂停,他们的数据就会被处理。

一旦调用triggerProcess,它所做的第一件事就是清除一个计时器,然后设置另一个计时器来在计时器到期时调用密集处理。我的想法是在triggerProcess中设置一个大约300ms的短超时,这样在从文本区域读取数据并进行处理之前,总有至少300ms的时间。如果键入了一个字符(如"I"),则会对其进行处理,但如果按顺序键入了几个字符,例如当键入一个单词时,则文本区域事件查看器会调用triggerProcess,则会清除每个字符的计时器并重新启动。当单词完成,并且从键盘到文本区域的流中存在间隙时,最后启动的计时器将过期,并对单词进行处理。我知道这会在处理文本区域内容时冻结打字员,但这种冻结比为每个字符冻结打字人要好得多。

我的代码看起来怎么样?会不会出了什么大问题?它可以改进吗?

感谢您花时间阅读本文,并感谢您的所有评论。

Peter

var delayTimer;  //global variable as opposed to local variable so that it can be cleared within function display.
function triggerProcess(){
   clearTimeout(delayTimer);
   delayTimer = 0;
   delayTimer=setTimeout(function(){
      // when the Timeout fires then
     // read the data from the textarea and have some very time consuming work on it 
   },300);
}

您试图实现的目标称为autocomplete

你的代码对我来说很酷,但如果我是你,我不会选择setTimeOut,因为这是一个破解,会让体验变慢。我会想到AJAX调用,而不是setTimeOut。使用AJAX(因为调用是异步的),您可以根据需要多次发送请求,而不会让用户遇到任何问题。每当用户键入并调用更改事件时,它都会询问新的匹配词,并在有匹配词时向用户显示新的匹配字。

我不知道你是否使用jQuery,但无论如何,jQuery UI有一个组件(请参阅这里的jQuery UI AUtocomplete)。感谢上帝,jQuery UI是一个开源项目,你可以在/UI/jQuery.UI.autocomplete.js上看到代码。如果你打开其他autocompleteEvents.js,你可以看到那里有四种事件类型:焦点、关闭、选择、更改。正如您在自动完成示例中看到的那样。

           $.ajax({
                    //Where you load the data, could be a backend server instead of a
                    // XML  file
                    url: "london.xml",
                    dataType: "xml",
                    success: function( xmlResponse ) {
                             //If matching any element from the london.xml file,
                             // Show the result in a menu or something
                    }
            });

它只是在任何事情发生更改时调用以获得新结果(就这么简单)。如果你不喜欢AJAX,试着使用回调,在发送新键入的单词后显示结果,并得到回复,而不是介于两者之间。

这里只是另一个自动完成的例子,我的第二个建议是:complete.ly。它有相同的概念。它只是添加了onchange和keyup事件:

     if (txt.addEventListener) {
        txt.addEventListener("input",  handler, false);
        txt.addEventListener('keyup',  handler, false);
        txt.addEventListener('change', handler, false);
    }

每当获取新值时,都会进行回调,检查是否有任何匹配项,并显示结果:

    var handler = function() {
        var value = txt.value;
        if (registerOnTextChangeOldValue !== value) {
            callback(value);
        }
    };

在此处阅读完整的源代码:complete.ly源代码我希望我的回答有意义!