web-dev-qa-db-fra.com

Comment lire un fichier avec async / wait correctement?

Je n'arrive pas à comprendre comment async/wait fonctionne. Je le comprends légèrement mais je ne peux pas le faire fonctionner.

function loadMonoCounter() {
    fs.readFileSync("monolitic.txt", "binary", async function(err, data) {
       return await new Buffer( data);
  });
}

module.exports.read = function() {
  console.log(loadMonoCounter());
};

Je sais que je pourrais utiliser readFileSync, mais si je le fais, je ne comprendrai jamais async/wait et j'enterrerai simplement le problème.

Objectif: Appeler loadMonoCounter () et renvoyer le contenu d'un fichier.

Ce fichier est incrémenté chaque fois que incrementMonoCounter () est appelé (chaque chargement de page). Le fichier contient le dump d'un tampon en binaire et est stocké sur un SSD.

Peu importe ce que je fais, je reçois une erreur ou indéfini dans la console.

61
Jeremy Dicaire

Pour utiliser await/async, vous avez besoin de méthodes qui renvoient des promesses. Les fonctions de base de l'API ne font pas cela sans wrappers comme 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);
})

Remarque: readFileSync ne prend pas de rappel, il renvoie les données ou lève une exception. Vous n'obtenez pas la valeur souhaitée, car la fonction que vous fournissez est ignorée et vous ne capturez pas la valeur de retour réelle.

121
tadman

Depuis Node v11.0.0, les promesses sont disponibles en mode natif sans promisify:

const fs = require('fs').promises;
async function loadMonoCounter() {
    const data = await fs.readFile("monolitic.txt", "binary");
    return new Buffer(data);
}
21
Joel

Ceci est la version TypeScript de la réponse de @ Joel

import { promises as fs } from 'fs';

async function loadMonoCounter() {
    const data = await fs.readFile('monolitic.txt', 'binary');
    return Buffer.from(file);
}

main();
1
HKTonyLee

Vous pouvez facilement envelopper la commande readFile avec une promesse comme ceci:

async function readFile(path) {
    return new Promise((resolve, reject) => {
      fs.readFile(path, 'utf8', function (err, data) {
        if (err) {
          reject(err);
        }
        resolve(data);
      });
    });
  }

puis utilisez:

await readFile("path/to/file");
0
Shlomi Schwartz