var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Nhật ký undefined, tại sao?
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Nhật ký undefined, tại sao?
Câu trả lời:
Để giải thích những gì @Raynos đã nói, chức năng bạn đã xác định là một cuộc gọi lại không đồng bộ. Nó không thực thi ngay lập tức, thay vào đó nó thực thi khi quá trình tải tập tin đã hoàn tất. Khi bạn gọi readFile, điều khiển được trả về ngay lập tức và dòng mã tiếp theo được thực thi. Vì vậy, khi bạn gọi console.log, cuộc gọi lại của bạn chưa được gọi và nội dung này chưa được đặt. Chào mừng bạn đến với lập trình không đồng bộ.
Cách tiếp cận ví dụ
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);
}
Hoặc tốt hơn, như ví dụ Raynos cho thấy, bọc cuộc gọi của bạn trong một chức năng và chuyển qua các cuộc gọi lại của riêng bạn. (Rõ ràng đây là cách thực hành tốt hơn) Tôi nghĩ rằng thói quen gói các cuộc gọi không đồng bộ của bạn trong chức năng gọi lại sẽ giúp bạn tiết kiệm rất nhiều rắc rối và mã lộn xộn.
function doSomething (callback) {
// any async callback invokes callback with response
}
doSomething (function doSomethingAfter(err, result) {
// process the async result
});
'utf8'sau tên tệp dưới dạng tham số bổ sung, nếu không nó sẽ chỉ trả về bộ đệm. Xem: stackoverflow.com/questions/9168737/ từ
Thực sự có một chức năng đồng bộ cho việc này:
http://nodejs.org/api/fs.html#fs_fs_readfilesync_filename_encoding
fs.readFile(filename, [encoding], [callback])
Đọc không đồng bộ toàn bộ nội dung của một tập tin. Thí dụ:
fs.readFile('/etc/passwd', function (err, data) {
if (err) throw err;
console.log(data);
});
Cuộc gọi lại được thông qua hai đối số (err, data), trong đó dữ liệu là nội dung của tệp.
Nếu không có mã hóa được chỉ định, thì bộ đệm thô được trả về.
fs.readFileSync(filename, [encoding])
Phiên bản đồng bộ của fs.readFile. Trả về nội dung của tệp có tên tệp.
Nếu mã hóa được chỉ định thì hàm này trả về một chuỗi. Nếu không, nó trả về một bộ đệm.
var text = fs.readFileSync('test.md','utf8')
console.log (text)
data. if (Buffer.isBuffer( data){ result = data.toString('utf8'); }Bây giờ chúng tôi đã chuyển đổi bộ đệm thành văn bản có thể đọc được. Điều này tốt cho việc đọc tệp văn bản gốc hoặc kiểm tra tệp theo các loại định dạng. Tôi có thể thực hiện thử / bắt để xem đó có phải là tệp JSON không; nhưng chỉ sau khi bộ đệm được chuyển đổi thành văn bản. Xem tại đây để biết thêm thông tin: nodejs.org/api/buffer.html
AF 42 F1. Rất thiết thực cho giao tiếp khách-máy chủ-khách hàng.
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), là callbackmột từ dành riêng? Ý tôi là, đây có phải là cách tiêu chuẩn để thực hiện các cuộc gọi lại cho các chức năng tùy chỉnh của bạn? Tôi mới bắt đầu học nút.
eventhoặc cbất kỳ tên nào bạn thích - đó không phải là một từ dành riêng trong Javascript và tôi sẽ giả sử như vậy kéo dài đến Node.js.
readContent(function (err, content)cho tôi một lỗi cú pháp khi sử dụng hàm làm tham số.
Các mzmô-đun cung cấp các phiên bản promisified của thư viện nút lõi. Sử dụng chúng rất đơn giản. Đầu tiên cài đặt thư viện ...
npm install mz
Sau đó...
const fs = require('mz/fs');
fs.readFile('./Index.html').then(contents => console.log(contents))
.catch(err => console.error(err));
Ngoài ra, bạn có thể viết chúng trong các hàm không đồng bộ:
async function myReadfile () {
try {
const file = await fs.readFile('./Index.html');
}
catch (err) { console.error( err ) }
};
Dòng này sẽ hoạt động,
const content = fs.readFileSync('./Index.html', 'utf8');
console.log(content);
fs.readFileSynclà phương thức đồng bộ, nên không cần awaitở đó. Await rất hữu ích với các lời hứa ( nodejs.org/api/fs.html#fs_fs_promises_api ), khi bạn muốn viết mã async với cú pháp tương tự như mã đồng bộ hóa.
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!");
});
});
}
cách đọc tệp đồng bộ và không đồng bộ:
//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);
Node Cheat Có sẵn tại read_file .
Như đã nói, fs.readFilelà một hành động không đồng bộ. Điều đó có nghĩa là khi bạn yêu cầu nút đọc một tệp, bạn cần xem xét rằng sẽ mất một thời gian và trong thời gian đó, nút tiếp tục chạy mã sau đây. Trong trường hợp của bạn, đó là:console.log(content); .
Nó giống như gửi một phần mã của bạn cho một chuyến đi dài (như đọc một tệp lớn).
Hãy xem các ý kiến mà tôi đã viết:
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);
Đó là lý do tại sao contentvẫn trống khi bạn đăng nhập nó. nút chưa lấy nội dung của tập tin.
Điều này có thể được giải quyết bằng cách di chuyển console.log(content)bên trong chức năng gọi lại, ngay sau đó content = data;. Bằng cách này, bạn sẽ thấy nhật ký khi nút đọc xong tệp và sau khi contentnhận được giá trị.
Sử dụng thư viện được tích hợp sẵn (Node 8+) để làm cho các hàm gọi lại cũ này trở nên thanh lịch hơn.
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');, không cần bọc produc.promisify.
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);
Điều này chỉ là do nút không đồng bộ và nó sẽ không chờ chức năng đọc và ngay khi chương trình khởi động, nó sẽ điều khiển giá trị là không xác định, điều này thực sự đúng vì không có giá trị nào được gán cho biến nội dung. Để xử lý chúng ta có thể sử dụng lời hứa, máy phát điện, v.v. Chúng ta có thể sử dụng lời hứa theo cách này.
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.
})
bạn có thể đọc tập tin bằng cách
var readMyFile = function(path, cb) {
fs.readFile(path, 'utf8', function(err, content) {
if (err) return cb(err, null);
cb(null, content);
});
};
Thêm vào bạn có thể viết vào tập tin,
var createMyFile = (path, data, cb) => {
fs.writeFile(path, data, function(err) {
if (err) return console.error(err);
cb();
});
};
và thậm chí xâu chuỗi nó lại với nhau
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);
}
});
};
Nói một cách đại khái, bạn đang xử lý với node.js về bản chất không đồng bộ.
Khi chúng tôi nói về async, chúng tôi đang nói về việc thực hiện hoặc xử lý thông tin hoặc dữ liệu trong khi xử lý một cái gì đó khác. Nó không đồng nghĩa với song song, xin được nhắc nhở.
Ma cua ban:
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
});
console.log(content);
Với mẫu của bạn, về cơ bản nó sẽ thực hiện phần console.log trước, do đó biến 'nội dung' không được xác định.
Nếu bạn thực sự muốn đầu ra, thay vào đó hãy làm một cái gì đó như thế này:
var content;
fs.readFile('./Index.html', function read(err, data) {
if (err) {
throw err;
}
content = data;
console.log(content);
});
Điều này là không đồng bộ. Sẽ khó để làm quen nhưng, nó là như vậy. Một lần nữa, đây là một lời giải thích sơ bộ nhưng nhanh chóng về sự không đồng bộ là gì.