var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Dzienniki undefined, dlaczego?
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Dzienniki undefined, dlaczego?
Odpowiedzi:
Aby rozwinąć to, co powiedział @Raynos, zdefiniowana funkcja to asynchroniczne wywołanie zwrotne. Nie uruchamia się od razu, raczej wykonuje się po zakończeniu ładowania pliku. Po wywołaniu readFile kontrola jest natychmiast zwracana i wykonywany jest następny wiersz kodu. Kiedy więc wywołujesz plik console.log, Twoje wywołanie zwrotne nie zostało jeszcze wywołane, a ta treść nie została jeszcze ustawiona. Witamy w programowaniu asynchronicznym.
Przykładowe podejścia
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);
}
Albo jeszcze lepiej, jak pokazuje przykład Raynos, zawiń swoje wywołanie w funkcji i przekaż własne wywołania zwrotne. (Najwyraźniej jest to lepsza praktyka). Myślę, że nabycie nawyku owijania wywołań asynchronicznych funkcją, która odbiera połączenia, pozwoli zaoszczędzić wiele problemów i niepotrzebnego kodu.
function doSomething (callback) {
// any async callback invokes callback with response
}
doSomething (function doSomethingAfter(err, result) {
// process the async result
});
'utf8'po nazwie pliku jako dodatkowy parametr, w przeciwnym razie po prostu zwróci bufor. Zobacz: stackoverflow.com/questions/9168737/…
Istnieje w tym celu funkcja synchroniczna:
http://nodejs.org/api/fs.html#fs_fs_readfilesync_filename_encoding
fs.readFile(filename, [encoding], [callback])
Asynchronicznie odczytuje całą zawartość pliku. Przykład:
fs.readFile('/etc/passwd', function (err, data) {
if (err) throw err;
console.log(data);
});
Do wywołania zwrotnego przekazywane są dwa argumenty (err, data), gdzie dane są zawartością pliku.
Jeśli nie określono kodowania, zwracany jest bufor surowy.
fs.readFileSync(filename, [encoding])
Synchroniczna wersja fs.readFile. Zwraca zawartość pliku o nazwie nazwa_pliku.
Jeśli określono kodowanie, funkcja ta zwraca ciąg znaków. W przeciwnym razie zwraca bufor.
var text = fs.readFileSync('test.md','utf8')
console.log (text)
data. if (Buffer.isBuffer( data){ result = data.toString('utf8'); }Teraz przekonwertowaliśmy bufor na czytelny tekst. Jest to dobre do odczytu pliku zwykłego tekstu lub testowania pliku pod kątem typów formatów. Mógłbym spróbować / złapać, aby zobaczyć, czy jest to na przykład plik JSON; ale dopiero po przekonwertowaniu bufora na tekst. Zajrzyj tutaj, aby uzyskać więcej informacji: nodejs.org/api/buffer.html
AF 42 F1. Bardzo praktyczne do komunikacji klient-serwer-klient.
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)jest callbacksłowo zastrzeżone? Mam na myśli, czy to standardowy sposób na implementację wywołań zwrotnych dla niestandardowych funkcji? Właśnie zacząłem uczyć się węzła.
eventalbo club dowolną nazwę - to nie jest słowo zarezerwowane w JavaScript, a ja zakładam samo rozciąga się Node.js.
readContent(function (err, content)daje mi błąd składniowy podczas używania funkcji jako parametru.
mzModuł zapewnia promisified wersje biblioteki węzła lokalnego. Korzystanie z nich jest proste. Najpierw zainstaluj bibliotekę ...
npm install mz
Następnie...
const fs = require('mz/fs');
fs.readFile('./Index.html').then(contents => console.log(contents))
.catch(err => console.error(err));
Możesz też napisać je w funkcjach asynchronicznych:
async function myReadfile () {
try {
const file = await fs.readFile('./Index.html');
}
catch (err) { console.error( err ) }
};
Ta linia będzie działać,
const content = fs.readFileSync('./Index.html', 'utf8');
console.log(content);
fs.readFileSyncjest metodą synchronizacji, więc nie ma takiej potrzeby await. Oczekiwanie jest przydatne w przypadku obietnic ( nodejs.org/api/fs.html#fs_fs_promises_api ), gdy chcesz napisać kod asynchroniczny ze składnią podobną do kodu synchronizacji.
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!");
});
});
}
sposób odczytu plików synchronizacji i asynchronizacji:
//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);
Węzeł Cheat Dostępny w pliku read_file .
Jak powiedziano, fs.readFilejest to działanie asynchroniczne. Oznacza to, że kiedy każesz węzłowi odczytać plik, musisz wziąć pod uwagę, że zajmie to trochę czasu, a tymczasem węzeł kontynuował działanie następującego kodu. W twoim przypadku to: console.log(content);.
To tak, jakby wysłać część kodu na długą podróż (jak czytanie dużego pliku).
Spójrz na komentarze, które napisałem:
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);
Dlatego contentjest nadal pusty po zalogowaniu. węzeł nie odzyskał jeszcze zawartości pliku.
Można to rozwiązać, przechodząc console.log(content)wewnątrz funkcji oddzwaniania, zaraz po niej content = data;. W ten sposób zobaczysz dziennik, gdy węzeł skończy czytać plik i po contentotrzymaniu wartości.
Użyj wbudowanej biblioteki promisify (Node 8+), aby te stare funkcje zwrotne były bardziej eleganckie.
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');, bez potrzeby użycia zawijania.
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);
Jest tak tylko dlatego, że węzeł jest asynchroniczny i nie będzie czekać na funkcję odczytu, a gdy tylko program się uruchomi, konsoluje wartość jako niezdefiniowaną, co jest prawdą, ponieważ do zmiennej treści nie przypisano żadnej wartości. Aby sobie z tym poradzić, możemy użyć obietnic, generatorów itp. Możemy wykorzystać obietnicę w ten sposób.
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.
})
możesz odczytać plik według
var readMyFile = function(path, cb) {
fs.readFile(path, 'utf8', function(err, content) {
if (err) return cb(err, null);
cb(null, content);
});
};
Dodając, możesz pisać do pliku,
var createMyFile = (path, data, cb) => {
fs.writeFile(path, data, function(err) {
if (err) return console.error(err);
cb();
});
};
a nawet połączyć to razem
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);
}
});
};
Mówiąc w skrócie, masz do czynienia z node.js, który ma charakter asynchroniczny.
Kiedy mówimy o asynchronizacji, mówimy o robieniu lub przetwarzaniu informacji lub danych, mając do czynienia z czymś innym. Przypominamy, że nie jest równoznaczne z równoległością.
Twój kod:
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
W przypadku próbki w zasadzie najpierw wykonuje część console.log, dlatego zmienna „content” jest niezdefiniowana.
Jeśli naprawdę potrzebujesz danych wyjściowych, zrób coś takiego:
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
console.log(content);
});
To jest asynchroniczne. Trudno się przyzwyczaić, ale tak właśnie jest. Ponownie jest to szorstkie, ale szybkie wyjaśnienie, czym jest asynchronizacja.