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 แสดงให้เห็นห่อสายของคุณในฟังก์ชั่นและผ่านในการเรียกกลับของคุณเอง (เห็นได้ชัดว่านี่เป็นวิธีปฏิบัติที่ดีกว่า) ฉันคิดว่าการใช้งานการโทรแบบ async ของคุณเป็นสิ่งที่ใช้ในการโทรกลับจะช่วยให้คุณประหยัดปัญหาและรหัสยุ่งได้
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มี การรอคอยมีประโยชน์กับสัญญา ( nodejs.org/api/fs.html#fs_fs_promises_api ) เมื่อคุณต้องการเขียนโค้ด async ด้วยไวยากรณ์ที่คล้ายกับรหัสซิงค์
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!");
});
});
}
วิธีการอ่านซิงค์และไฟล์ async:
//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);
อย่างที่ได้กล่าวไปแล้วว่า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 ในตัว (โหนด 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');โดยไม่จำเป็นต้องใช้
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.
})
ฟังก์ชั่นต่อไปนี้จะทำงานสำหรับasyncห่อหรือสัญญาthenโซ่
const readFileAsync = async (path) => fs.readFileSync(path, 'utf8');
คุณสามารถอ่านไฟล์ได้
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 ซึ่งเป็นแบบอะซิงโครนัสในธรรมชาติ
เมื่อเราพูดถึง async เรากำลังพูดถึงการทำหรือประมวลผลข้อมูลหรือข้อมูลในขณะที่จัดการกับสิ่งอื่น มันไม่ได้หมายถึงขนานกันโปรดได้รับการเตือน
รหัสของคุณ:
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
ด้วยตัวอย่างของคุณโดยทั่วไปแล้วมันจะทำการ console.log ส่วนแรกจึงทำให้ตัวแปร 'เนื้อหา' ไม่ได้กำหนด
หากคุณต้องการเอาท์พุทให้ทำสิ่งนี้แทน:
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
console.log(content);
});
นี่คืออะซิงโครนัส มันจะยากที่จะชินกับมัน แต่มันคือสิ่งที่มันเป็น อีกครั้งนี่เป็นคำอธิบายคร่าวๆ แต่อย่างรวดเร็วสำหรับ async คืออะไร