var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Журналы undefined
, почему?
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Журналы undefined
, почему?
Чтобы пояснить, что сказал @Raynos, определенная вами функция является асинхронным обратным вызовом. Он не выполняется сразу, а выполняется после завершения загрузки файла. Когда вы вызываете readFile, управление возвращается немедленно и выполняется следующая строка кода. Поэтому, когда вы вызываете console.log, ваш обратный вызов еще не был вызван, и этот контент еще не был установлен. Добро пожаловать в асинхронное программирование.
Пример подходов
const fs = require('fs');
var content;
// First I want to read the file
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
// Invoke the next step here however you like
console.log(content); // Put all of the code here (not the best solution)
processFile(); // Or put the next step in a function and invoke it
});
function processFile() {
console.log(content);
}
Или, что еще лучше, как показывает пример Raynos, оберните ваш вызов в функцию и передайте свои собственные обратные вызовы. (Очевидно, это лучшая практика). Я думаю, что привычка заключать в асинхронные вызовы функцию, которая принимает обратный вызов, избавит вас от большого количества хлопот и грязного кода.
function doSomething (callback) {
// any async callback invokes callback with response
}
doSomething (function doSomethingAfter(err, result) {
// process the async result
});
Для этого существует синхронная функция:
http://nodejs.org/api/fs.html#fs_fs_readfilesync_filename_encoding
fs.readFile(filename, [encoding], [callback])
Асинхронно считывает все содержимое файла. Пример:
fs.readFile('/etc/passwd', function (err, data) {
if (err) throw err;
console.log(data);
});
Обратный вызов передается двумя аргументами (err, data), где данные являются содержимым файла.
Если кодировка не указана, возвращается исходный буфер.
fs.readFileSync(filename, [encoding])
Синхронная версия fs.readFile. Возвращает содержимое файла с именем filename.
Если кодировка задана, эта функция возвращает строку. В противном случае он возвращает буфер.
var text = fs.readFileSync('test.md','utf8')
console.log (text)
function readContent(callback) {
fs.readFile("./Index.html", function (err, content) {
if (err) return callback(err)
callback(null, content)
})
}
readContent(function (err, content) {
console.log(content)
})
Модуль mz
предоставляет многообещающие версии основной библиотеки node. Использование их просто. Сначала установите библиотеку...
npm install mz
Тогда...
const fs = require('mz/fs');
fs.readFile('./Index.html').then(contents => console.log(contents))
.catch(err => console.error(err));
В качестве альтернативы вы можете записать их в асинхронных функциях:
async function myReadfile () {
try {
const file = await fs.readFile('./Index.html');
}
catch (err) { console.error( err ) }
};
var data = fs.readFileSync('tmp/reltioconfig.json','utf8');
используйте это для синхронного вызова файла, без кодирования его вывода вывода в виде буфера.
Как уже говорилось, fs.readFile
- это асинхронное действие. Это означает, что когда вы указываете узлу читать файл, вам нужно учитывать, что это займет некоторое время, а тем временем узел продолжал выполнять следующий код. В вашем случае это: console.log(content);
,
Это похоже на отправку какой-то части вашего кода для длительной поездки (например, чтение большого файла).
Посмотрите на комментарии, которые я написал:
var content;
// node, go fetch this file. when you come back, please run this "read" callback function
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
// in the meantime, please continue and run this console.log
console.log(content);
Вот почему content
все еще пуст, когда вы входите в него. узел еще не получил содержимое файла.
Это может быть решено перемещением console.log(content)
внутри функции обратного вызова, сразу после content = data;
, Таким образом, вы увидите журнал, когда узел завершит чтение файла и после того, как content
получит значение.
Синхронизация и асинхронное чтение файла:
//fs module to read file in sync and async way
var fs = require('fs'),
filePath = './sample_files/sample_css.css';
// this for async way
/*fs.readFile(filePath, 'utf8', function (err, data) {
if (err) throw err;
console.log(data);
});*/
//this is sync way
var css = fs.readFileSync(filePath, 'utf8');
console.log(css);
Чит-узел доступен в файле read_file.
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!");
});
});
}
var fs = require('fs');
var path = (process.cwd()+"\\text.txt");
fs.readFile(path , function(err,data)
{
if(err)
console.log(err)
else
console.log(data.toString());
});
Используйте встроенную библиотеку 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);
}
}
Вы можете прочитать файл по
var readMyFile = function(path, cb) {
fs.readFile(path, 'utf8', function(err, content) {
if (err) return cb(err, null);
cb(null, content);
});
};
Добавив, вы можете написать в файл,
var createMyFile = (path, data, cb) => {
fs.writeFile(path, data, function(err) {
if (err) return console.error(err);
cb();
});
};
и даже связать это вместе
var readFileAndConvertToSentence = function(path, callback) {
readMyFile(path, function(err, content) {
if (err) {
callback(err, null);
} else {
var sentence = content.split('\n').join(' ');
callback(null, sentence);
}
});
};
Грубо говоря, вы имеете дело с 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);
});
Это асинхронно. Будет трудно привыкнуть, но это то, что есть. Опять же, это грубое, но быстрое объяснение того, что такое асинхронность.
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Это просто потому, что узел асинхронный, и он не будет ждать функцию чтения, и, как только программа запустится, он будет поддерживать значение как неопределенное, что на самом деле верно, потому что нет значения, назначенного переменной содержимого. Для обработки мы можем использовать обещания, генераторы и т.д. Мы можем использовать обещание таким образом.
new Promise((resolve,reject)=>{
fs.readFile('./index.html','utf-8',(err, data)=>{
if (err) {
reject(err); // in the case of error, control flow goes to the catch block with the error occured.
}
else{
resolve(data); // in the case of success, control flow goes to the then block with the content of the file.
}
});
})
.then((data)=>{
console.log(data); // use your content of the file here (in this then).
})
.catch((err)=>{
throw err; // handle error here.
})