valid - try catch async await javascript




Usando el sistema de archivos en node.js con async/await (5)

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();

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.


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.


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');

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






fs