valid try only node funciona example como catch await async javascript node.js async-await fs

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... };