回答:
@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);
}
あるいは、レイノスの例が示すように、呼び出しを関数にラップし、独自のコールバックを渡します。(どうやらこれはより良い習慣です)コールバックを受け取る関数で非同期呼び出しをラップする習慣を身につけることで、多くの問題と面倒なコードを節約できます。
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);
});
コールバックには2つの引数(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ファイルかどうかを確認するためにtry / catchを実行できます。ただし、バッファがテキストに変換された後のみ。詳細については、ここを参照してください。nodejs.org
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モジュールは、コアノードライブラリの保証されたバージョンを提供します。それらを使用するのは簡単です。最初にライブラリをインストールします...
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は、同期コードと同様の構文で非同期コードを記述したい場合に、promise(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ラップは不要です。
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
これは、ノードが非同期であり、読み取り関数を待機せず、プログラムが起動するとすぐに値が未定義としてコンソールに表示されるためです。コンテンツ変数に値が割り当てられていないため、実際にはtrueです。処理するには、promise、ジェネレータなどを使用できます。promiseをこのように使用できます。
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);
});
これは非同期です。慣れるのは難しいですが、それはそれです。繰り返しますが、これは非同期とは何かについての大まかではありますが迅速な説明です。