var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});
console.log(content);

日志未定义,为什么?


当前回答

使用内置的promisify库(Node 8+)使这些旧的回调函数更加优雅。

const fs = require('fs');
const util = require('util');

const readFile = util.promisify(fs.readFile);

async function doStuff() {
  try {
    const content = await readFile(filePath, 'utf8');
    console.log(content);
  } catch (e) {
    console.error(e);
  }
}

其他回答

粗略地说,你在处理本质上是异步的node.js。

当我们谈论异步时,我们谈论的是在处理其他事情的同时处理信息或数据。请注意,它不是平行的同义词。

你的代码:

var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});
console.log(content);

在您的示例中,它基本上首先执行console.log部分,因此变量“content”未定义。

如果你真的想要输出,可以这样做:

var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
    console.log(content);
});

这是异步的。这很难适应,但事实就是这样。 同样,这是对异步的粗略但快速的解释。

为了详细说明@Raynos所说的内容,您定义的函数是一个异步回调。它不会立即执行,而是在文件加载完成后执行。当调用readFile时,立即返回控制,并执行下一行代码。因此,当您调用console.log时,您的回调还没有被调用,这个内容还没有设置。欢迎学习异步编程。

例子的方法

const fs = require('fs');
// First I want to read the file
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    const content = data;

    // Invoke the next step here however you like
    console.log(content);   // Put all of the code here (not the best solution)
    processFile(content);   // Or put the next step in a function and invoke it
});

function processFile(content) {
    console.log(content);
}

或者更好的是,如Raynos示例所示,将调用包装在函数中,并传递自己的回调。(显然这是更好的实践)我认为养成将异步调用包装在接受回调的函数中的习惯将为您节省大量麻烦和混乱的代码。

function doSomething (callback) {
    // any async callback invokes callback with response
}

doSomething (function doSomethingAfter(err, result) {
    // process the async result
});

下面是函数将工作异步包装或承诺然后链

const readFileAsync =  async (path) => fs.readFileSync(path, 'utf8');

我喜欢使用fs-extra,因为所有函数都是承诺的,开箱即用,所以可以使用await。所以你的代码可以是这样的:

(async () => {
   try {
      const content = await fs.readFile('./Index.html');
      console.log(content);
   } catch (err) {
      console.error(err);
   }
})();
const fs = require('fs')
function readDemo1(file1) {
    return new Promise(function (resolve, reject) {
        fs.readFile(file1, 'utf8', function (err, dataDemo1) {
            if (err)
                reject(err);
            else
                resolve(dataDemo1);
        });
    });
}
async function copyFile() {

    try {
        let dataDemo1 = await readDemo1('url')
        dataDemo1 += '\n' +  await readDemo1('url')

        await writeDemo2(dataDemo1)
        console.log(dataDemo1)
    } catch (error) {
        console.error(error);
    }
}
copyFile();

function writeDemo2(dataDemo1) {
    return new Promise(function(resolve, reject) {
      fs.writeFile('text.txt', dataDemo1, 'utf8', function(err) {
        if (err)
          reject(err);
        else
          resolve("Promise Success!");
      });
    });
  }