如何做延迟来执行搜索和替换功能。带延迟

时间:2016-10-24 22:13:57

标签: javascript node.js

所以这里是一个数组,我想对数组中的每个项进行查找和替换,并搜索键并替换为值,但这不起作用。它搜索草莓5次。

也不知道我是否需要延迟这样的事情?

var path  = require('path');
var fs    = require('fs');
var cnf   = {
  apples        : 'ill replace this value with this',
  pears         : 'ill replace this value with this',
  bananaas      : 'ill replace this value with this',
  peaches       : 'ill replace this value with this',
  strawberries  : 'ill replace this value with this'
}

for(var k in cnf) {
  fs.readFile(path.resolve('./file-to-search.txt'), 'utf8', function (err,data) {
    if (err)  return console.log(err)
    var searchReplace = data.replace(k, cnf[k])
    fs.writeFile(path.resolve('./file-to-search.txt'), searchReplace, 'utf8', function (err) {
      if (err) return console.log(err)
    });
  });
}

4 个答案:

答案 0 :(得分:1)

不是在每次搜索和/或替换时读取/写入文件,而是读取文件一次,执行每次搜索和替换,然后写出最终结果。

fs.readFile(path.resolve('./file-to-search.txt'), 'utf8', function (err,data) {
  if (err)  return console.log(err);
  for(var k in cnf) {
    data = data.replace(k, cnf[k]);
  }
  fs.writeFile(path.resolve('./file-to-search.txt'), data, 'utf8', function (err) {
    if (err) return console.log(err);
  });
});

答案 1 :(得分:0)

问题是fs.readFile是异步运行的。这意味着变量k在第一次调用fs.readFile之前完成所有5个可能的值。由于k是在父作用域中定义的,因此值随循环而变化。

你需要的是一个封闭。

var path  = require('path');
var fs    = require('fs');
var cnf   = {
  apples        : 'ill replace this value with this',
  pears         : 'ill replace this value with this',
  bananaas      : 'ill replace this value with this',
  peaches       : 'ill replace this value with this',
  strawberries  : 'ill replace this value with this'
}

for(var k in cnf) {
  fs.readFile(path.resolve('./file-to-search.txt'), 'utf8', (function (val) { 
    var v = val; // Closure around the current state of val
    // Return a copy of the function we want to run with the saved state
    return function (err, data) {
        if (err)  return console.log(err)
        var searchReplace = data.replace(v, cnf[v])
        fs.writeFile(path.resolve('./file-to-search.txt'), searchReplace, 'utf8', function (err) {
            if (err) return console.log(err)
        }); // End write
      }); // End Read
   })(k); // End Closure, call with k to get saved state
}

只是一句警告,当您遇到这种情况时(使用异步运行的功能)添加延迟有时可能会起作用。但是,由于您无法保证异步功能所需的时间,因此您可能偶尔会出现乱序运行的情况,这可能非常难以排除故障(竞争条件)。始终使用回调/闭包而不是延迟。

答案 2 :(得分:0)

问题是fs.readFile是异步的,这意味着当它的回调运行时循环已经完成,所以k指的是最后一个元素,即草莓。 / p>

要解决此问题,您需要将此函数包装在闭包中:

for (var k in cnf) {
    (function(k) {
        fs.readFile(path.resolve('./file-to-search.txt'), 'utf8', function(err, data) {
            if (err) return console.log(err)
            var searchReplace = data.replace(k, cnf[k])
            fs.writeFile(path.resolve('./file-to-search.txt'), searchReplace, 'utf8', function(err) {
                if (err) return console.log(err)
            });
        });
    })(k);
}

您现在在循环中有一个全局k var,在k内有一个私有(function(k) {}) var,它保留了k的值,因为它在循环。

答案 3 :(得分:0)

有时readFileSync()在这种情况下很有用。