web-dev-qa-db-fra.com

lecture de fichier avec promesses ES6

let arr = [];

function getData(fileName, type) {
    return fs.readFile(fileName,'utf8', (err, data) => {
        if (err) throw err;

        return new Promise(function(resolve, reject) {
            for (let i = 0; i < data.length; i++) {
                arr.Push(data[i]);
            }

            resolve();
        });
    });
}

getData('./file.txt', 'sample').then((data) => {
    console.log(data);
});

Lorsque j'utilise le code ci-dessus et que je l'exécute en ligne de commande à l'aide de nodejs, l'erreur suivante apparaît.

getData('./file.txt', 'sample').then((data) => {
                               ^

TypeError: Cannot read property 'then' of undefined

Comment puis-je résoudre ça?

6
2619

Vous voudrez envelopper la totalité de l'appel fs.readFile dans une nouvelle Promise, puis rejeter ou résoudre la promesse en fonction du résultat du rappel:

function getData(fileName, type) {
  return new Promise(function(resolve, reject){
    fs.readFile(fileName, type, (err, data) => {
        err ? reject(err) : resolve(data);
    });
  });
}
19
hackerrdave

Personne n'a parlé de util.promisify donc je vais poster, quelle que soit l'âge de la question… .. Pourquoi avez-vous ce message?

getData('./file.txt', 'sample').then((data) => {
                               ^

TypeError: Cannot read property 'then' of undefined

getData est un wrapper pour le fichier "fs.readFile" ici. fs.readfile n'est pas une instance: il n'implémente pas une fonction then. Il est construit sur l'autre motif, le motif de rappel. Les promesses les plus connues sont Promises, et c'est ce que vous voulez obtenir de readFile, je crois. Petit rappel: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

Donc, ce que vous pouvez faire est soit de l'implémenter vous-même comme @hackerrdave ou je suggérerais d'utiliser promisify: cette fonction est une fonction intégrée de Node.js qui a été implémentée pour transformer la fonction basée sur le rappel en promis. Vous le trouverez ici: https://nodejs.org/api/util.html#util_util_promisify_original

Il fait fondamentalement la même chose que @hackerrdave mais il est plus robuste et intègre.

Voici comment l'utiliser:

const util = require('util');
const fs = require('fs');

const readFile = util.promisify(fs.readFile)
readFile("path/to/myfile").then(file => console.log(file))
12
Théophile Pace
const getData = (fileName, type) =>
  new Promise((resolve, reject) =>
    fs.readFile(fileName, type, (err, data) => {
      //if has error reject, otherwise resolve
      return err ? reject(err) : resolve(data);
    })
  );

getData('./file.txt', 'utf8')
  .then(data => console.log('Data: ', data))
  .catch(error => console.log('Error: ', error));
7
adrice727

Voici un one-liner à partir du noeud 10.2.0:

(async () => console.log(String(await require('fs').promises.readFile('./file.txt'))))();

Oui, il est maintenant hors de la boîte.

5
Elias Goss

Mise à jour pour le noeud actuel À partir du noeud 10.0.0, vous pouvez maintenant utiliser fs.promises :

const fs = require('fs')

(async function(){
    var fileContents = await fs.promises.readFile(FILENAME)
    var data = JSON.parse(fileContents)
})()
1
mikemaccana