nodejs经常写文件

时间:2016-06-05 04:39:56

标签: javascript node.js asynchronous

我有一个监听器来监听内容的变化,一旦内容被修改,它就会发出处理函数:

$('#editor').on('onchange', () => changeHandler('...','...'));

function changeHandler(filePath, content){
    var ws = fs.createWriteStream(filePath, 'utf8');
    ws.write(content);
}

我的问题是'onchange'经常发生,因此'write file'经常处理,在此期间它可能会丢失数据。 有人可以提出任何建议吗?

更新 现在我根据下面的答案更改了代码:

this.buffer = null; //used to cache

// once content changed, maybe too often
changeHandler() {        
    if (this.editor.curOp && this.editor.curOp.command.name) {
        var id = $('.nav-items li.active .lk-hosts').attr('data-hosts-id');
        var content = this.editor.getValue();
        // cache data, not immediately write to file
        this.buffer = {id: id, content: content};
    }        
}

setInterval(()=> {
        // means there's data in cache
        if (this.buffer !== null) {
            let id = this.buffer.id;
            let content = this.buffer.content;
            // reset cache to null
            this.buffer = null;
            // write file
            this.writeContent(id, content, (err)=> {
            })
        }
    }, 800);

感谢所有答案!

3 个答案:

答案 0 :(得分:1)

下面的示例显示了如何进行去抖动事件处理,尽管它不是node.js代码,它在概念上是相同的。

// eventEmitter variable to use
var emitter = new EventEmitter();

// dom element change event
$('#editor').on('input', function(event) {
  emitter.emit('changeEvent', event.target.value);
});

// event listener, which debounces change event of input
emitter.on('changeEvent', debounce(function(data) {
  writeFile('li', data);
}, 1000)); // <== debounce for 1second


// sample emitter, for demo
// we don't have access to nodejs EventEmitter class in Stackoverflow 
// don't use in production
function EventEmitter() {
  var callbacks = [];
  return {
    on: function(eventName, fn) {
      callbacks.push({
        eventName: eventName,
        callback: fn
      })
    },
    emit: function(eventName, payload) {
      var fn = callbacks.find(function(item) {
        return item.eventName === eventName;
      });
      if (fn) {
        fn.callback(payload);
      }
    }
  }
}

// simple logger for demo purpose
// emulates write file 
function writeFile(name, content) {
  var $elem = $(document.createElement(name));
  $elem.text(content);
  $('#logger').append($elem);
}

// throttle function - reduces fn call with timeout
// credits: https://remysharp.com/2010/07/21/throttling-function-calls
function debounce(fn, delay) {
  var timer = null;
  return function() {
    var context = this,
      args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  };
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="editor" placeholder="Enter text, this will emit change event"></textarea>

<p>
  Notice the 1sec throttle (write something, pause for 1sec, write again)
</p>

<ul id="logger"></ul>

去抖功能也可用于textarea更改事件

// debounce emitting
$('#editor').on('input', debounce(function(event) {
  emitter.emit('changeEvent', event.target.value);
}, 1000));

// write file when received event without debounce
emitter.on('changeEvent', function(data){
  logElement('li', data);
});

答案 1 :(得分:0)

Underscore库具有_.throttle()_.debounce()功能。

答案 2 :(得分:0)

为什么不简单地构建一个缓冲区来收集书面文本,然后只有当你有一定数量的写入时才写入文件:

$('#editor').on('onchange', () => changeHandler('...','...'));

var writeBuffer = ''; // can also make this an array
var writeBufferSize = 0;
var filePath = 'path_to_file';
var ws = fs.createWriteStream(filePath, 'utf8');

function changeHandler(content){
    if (writeBufferSize == SOME_THRESHOLD) {
        ws.write(writeBuffer);
        writeBuffer = '';
        writeBufferSize = 0;
    } else {
        writeBuffer += content + '\n';
        writeBufferSize++;
    }
}

如果选择的写入缓冲区阈值太大,您可能希望将写入委托给某个工作线程并行完成,在这种情况下,您可以创建另一个临时写入缓冲区来填充正在写原文,然后切换两个。