Как правильно читать файл с помощью async/await?
Я не могу понять, как работает async/await. Я немного понимаю, но не могу заставить это работать.
function loadMonoCounter() {
fs.readFileSync("monolitic.txt", "binary", async function(err, data) {
return await new Buffer( data);
});
}
module.exports.read = function() {
console.log(loadMonoCounter());
};
Я знаю, что могу использовать readFileSync, но если я это сделаю, я знаю, что никогда не пойму async/await, и я просто решу проблему.
Цель: вызвать loadMonoCounter() и вернуть содержимое файла.
Этот файл увеличивается каждый раз при вызове incrementMonoCounter() (при каждой загрузке страницы). Файл содержит дамп буфера в двоичном виде и хранится на SSD.
Независимо от того, что я делаю, я получаю сообщение об ошибке или неопределенное в консоли.
13 ответов
Использовать await
/ async
вам нужны методы, которые возвращают обещания. Основные функции API не делают этого без таких оболочек, как promisify
:
const fs = require('fs');
const util = require('util');
// Convert fs.readFile into Promise version of same
const readFile = util.promisify(fs.readFile);
async function getStuff() {
return await readFile('test');
}
// Can't use `await` outside of an async function so you need to chain
// with then()
getStuff().then(data => {
console.log(data);
})
Как примечание, readFileSync
не принимает обратный вызов, возвращает данные или создает исключение. Вы не получаете желаемое значение, потому что та функция, которую вы предоставляете, игнорируется и вы не фиксируете фактическое возвращаемое значение.
Поскольку Node v11.0.0 fs promises изначально доступен без promisify
:
const fs = require('fs').promises;
async function loadMonoCounter() {
const data = await fs.readFile("monolitic.txt", "binary");
return new Buffer(data);
}
Это TypeScript-версия ответа @Joel. Его можно использовать после Node 11.0:
import { promises as fs } from 'fs';
async function loadMonoCounter() {
const data = await fs.readFile('monolitic.txt', 'binary');
return Buffer.from(data);
}
Вы можете использовать fs.promises
доступно изначально, начиная с Node v11.0.0
import fs from 'fs';
const readFile = async filePath => {
try {
const data = await fs.promises.readFile(filePath, 'utf8')
return data
}
catch(err) {
console.log(err)
}
}
Вы можете легко обернуть команду readFile таким обещанием:
async function readFile(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, 'utf8', function (err, data) {
if (err) {
reject(err);
}
resolve(data);
});
});
}
затем используйте:
await readFile("path/to/file");
С узла v14.0.0
const {readFile} = require('fs/promises');
const myFunction = async()=>{
const result = await readFile('monolitic.txt','binary')
console.log(result)
}
myFunction()
Чтобы он оставался лаконичным и сохранял все функциональные возможности
fs
:
const fs = require('fs');
const fsPromises = fs.promises;
async function loadMonoCounter() {
const data = await fsPromises.readFile('monolitic.txt', 'binary');
return new Buffer(data);
}
Импорт
fs
и
fs.promises
отдельно даст доступ ко всей
fs
API, при этом сохраняя его более читабельным... Так что что-то вроде следующего примера легко выполнить.
// the 'next example'
fsPromises.access('monolitic.txt', fs.constants.R_OK | fs.constants.W_OK)
.then(() => console.log('can access'))
.catch(() => console.error('cannot access'));
E сть fs.readFileSync( path, options )
метод, который является синхронным.
const fs = require("fs");
const util = require("util");
const readFile = util.promisify(fs.readFile);
const getContent = async () => {
let my_content;
try {
const { toJSON } = await readFile("credentials.json");
my_content = toJSON();
console.log(my_content);
} catch (e) {
console.log("Error loading client secret file:", e);
}
};
Я читаю файл с помощью
Promise
. Для меня правильно:
const fs = require('fs')
//function which return Promise
const read = (path, type) => new Promise((resolve, reject) => {
fs.readFile(path, type, (err, file) => {
if (err) reject(err)
resolve(file)
})
})
//example how call this function
read('file.txt', 'utf8')
.then((file) => console.log('your file is '+file))
.catch((err) => console.log('error reading file '+err))
//another example how call function inside async
async function func() {
let file = await read('file.txt', 'utf8')
console.log('your file is '+file)
}
Это создает строку из содержимого вашего файла, вам не нужно использовать обещания, чтобы это работало.
const fs = require('fs');
const data = fs.readFileSync("./path/to/file.json", "binary");
Вы можете найти мой подход ниже: сначала мне потребовалась fs как fsBase, затем я поместил «обещания» в переменную fs.
const fsBase = require('fs');
const fs = fsBase.promises
const fn = async () => {
const data = await fs.readFile('example.txt', 'utf8');
console.log(data);
};
fn();
см. этот пример https://www.geeksforgeeks.org/node-js-fs-readfile-method/