javascript - try - Usando el sistema de archivos en node.js con async/await
node js await catch (7)
Me gustaría usar async / await con algunas operaciones del sistema de archivos.
Normalmente async / await funciona bien porque uso
babel-plugin-syntax-async-functions
.
Pero con este código me encuentro con el caso if donde los
names
no están definidos:
import fs from ''fs'';
async function myF() {
let names;
try {
names = await fs.readdir(''path/to/dir'');
} catch (e) {
console.log(''e'', e);
}
if (names === undefined) {
console.log(''undefined'');
} else {
console.log(''First Name'', names[0]);
}
}
myF();
Cuando reconstruyo el código en la versión de devolución de llamada, todo está bien y obtengo los nombres de archivo. Gracias por tus sugerencias.
Asíncrono nativo espera funciones de estilo fs desde la versión 11
Desde Node.JS 11.0.0 (estable) y la versión 10.0.0 (experimental), tiene acceso a los métodos del sistema de archivos que ya están prometidos y puede usarlos con el manejo de excepciones de
try catch
lugar de verificar si la devolución de llamada regresa El valor contiene un error.
¡La API es muy limpia y elegante!
Simplemente use el miembro
.promises
del objeto
fs
:
import fs from ''fs'';
const fsPromises = fs.promises;
async function listDir() {
try {
return await fsPromises.readdir(''path/to/dir'');
} catch (err) {
console.error(''Error occured while reading directory!'', err);
}
}
listDir();
Node.js 8.0.0
Asíncrono nativo / espera
Promisificar
Desde esta versión, puede usar la función nativa Node.js de la biblioteca util .
const fs = require(''fs'')
const { promisify } = require(''util'')
const readFileAsync = promisify(fs.readFile)
const writeFileAsync = promisify(fs.writeFile)
const run = async () => {
const res = await readFileAsync(''./data.json'')
console.log(res)
}
run()
Envoltura de promesas
const fs = require(''fs'')
const readFile = (path, opts = ''utf8'') =>
new Promise((resolve, reject) => {
fs.readFile(path, opts, (err, data) => {
if (err) reject(err)
else resolve(data)
})
})
const writeFile = (path, data, opts = ''utf8'') =>
new Promise((resolve, reject) => {
fs.writeFile(path, data, opts, (err) => {
if (err) reject(err)
else resolve()
})
})
module.exports = {
readFile,
writeFile
}
...
// in some file, with imported functions above
// in async block
const run = async () => {
const res = await readFile(''./data.json'')
console.log(res)
}
run()
Consejo
Utilice siempre
try..catch
para los bloques de espera, si no desea volver a lanzar la excepción superior.
Comenzando con el nodo 8.0.0, puede usar esto:
const fs = require(''fs'');
const util = require(''util'');
const readdir = util.promisify(fs.readdir);
async function myF() {
let names;
try {
{err, names} = await readdir(''path/to/dir'');
if (err) {
// Handle the error.
}
} catch (e) {
console.log(''e'', e);
}
if (names === undefined) {
console.log(''undefined'');
} else {
console.log(''First Name'', names[0]);
}
}
myF();
Ver https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original
Esto es lo que funcionó para mí:
const fsp = require(''fs-promise'');
(async () => {
try {
const names = await fsp.readdir(''path/to/dir'');
console.log(names[0]);
} catch (e) {
console.log(''error: '', e);
}
})();
Este código funciona en el nodo 7.6 sin babel cuando el
indicador de armonía
está habilitado:
node --harmony my-script.js
.
Y comenzando con el nodo 7.7,
¡ni siquiera necesita esta bandera
!
La biblioteca
fsp
incluida al principio es solo un contenedor prometido para
fs
(y
fs-ext
).
¡Estoy realmente entusiasmado con lo que puedes hacer en el nodo sin babel en estos días!
¡La
async
/
await
nativa hace que escribir código sea un placer!
ACTUALIZACIÓN 2017-06: el
módulo fs-promise fue desaprobado.
Utilice
fs-extra
lugar con la misma API.
Puede producir el comportamiento incorrecto porque File-Api
fs.readdir
no devuelve una promesa.
Solo toma una devolución de llamada.
Si desea utilizar la sintaxis de espera asíncrona, puede ''prometer'' la función de esta manera:
function readdirAsync(path) {
return new Promise(function (resolve, reject) {
fs.readdir(path, function (error, result) {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
y llámalo en su lugar:
names = await readdirAsync(''path/to/dir'');
Se recomienda utilizar un paquete npm como https://github.com/davetemplin/async-file , en comparación con las funciones personalizadas. Por ejemplo:
import * as fs from ''async-file'';
await fs.rename(''/tmp/hello'', ''/tmp/world'');
await fs.appendFile(''message.txt'', ''data to append'');
await fs.access(''/etc/passd'', fs.constants.R_OK | fs.constants.W_OK);
var stats = await fs.stat(''/tmp/hello'', ''/tmp/world'');
Otras respuestas están desactualizadas
Tengo este pequeño módulo de ayuda que exporta versiones
promisified
de funciones
fs
const fs = require("fs");
const {promisify} = require("util")
module.exports = {
readdir: promisify(fs.readdir),
readFile: promisify(fs.readFile),
writeFile: promisify(fs.writeFile)
// etc...
};