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');
// 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
});
'utf8'после имени файла в качестве дополнительного параметра, иначе он просто вернет буфер. См .: stackoverflow.com/questions/9168737/…
На самом деле есть синхронная функция для этого:
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), где data - это содержимое файла.
Если кодировка не указана, возвращается необработанный буфер.
fs.readFileSync(filename, [encoding])
Синхронная версия fs.readFile. Возвращает содержимое файла с именем filename.
Если указано кодирование, то эта функция возвращает строку. В противном случае он возвращает буфер.
var text = fs.readFileSync('test.md','utf8')
console.log (text)
data. if (Buffer.isBuffer( data){ result = data.toString('utf8'); }Теперь мы преобразовали буфер в читаемый текст. Это хорошо для чтения открытого текста или проверки файла на соответствие форматам. Я мог бы сделать попытку / поймать, чтобы увидеть, если это, например, файл JSON; но только после того, как буфер преобразован в текст. Посмотрите здесь для получения дополнительной информации: nodejs.org/api/buffer.html
AF 42 F1. Очень практично для общения клиент-сервер-клиент.
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)
})
function readContent(callback), callbackзарезервированное слово? Я имею в виду, это стандартный способ реализации обратных вызовов для ваших пользовательских функций? Я только начал изучать узел.
eventили cлюбое другое имя, которое вам нравится - это не зарезервированное слово в Javascript, и я предполагаю, что то же самое распространяется на Node.js.
readContent(function (err, content)выдает синтаксическую ошибку при использовании функции в качестве параметра.
mzМодуль обеспечивает promisified версии библиотеки ядра узла. Использовать их просто. Сначала установите библиотеку ...
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 ) }
};
Эта линия будет работать,
const content = fs.readFileSync('./Index.html', 'utf8');
console.log(content);
fs.readFileSyncЭто метод синхронизации, поэтому нет необходимости await. Await полезен с обещаниями ( nodejs.org/api/fs.html#fs_fs_promises_api ), когда вы хотите написать асинхронный код с синтаксисом, похожим на код синхронизации.
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!");
});
});
}
Синхронизация и асинхронное чтение файла:
//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 .
Как сказано, 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получит значение.
Используйте встроенную библиотеку 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);
}
}
const doStuff = async (filePath) => fs.readFileSync(filePath, 'utf8');, не нужно использовать util.promisify wrap.
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());
});
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.
})
Вы можете прочитать файл по
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);
});
Это асинхронно. Будет трудно привыкнуть, но это то, что есть. Опять же, это грубое, но быстрое объяснение того, что такое асинхронность.