web-dev-qa-db-fra.com

fs.writeFile dans un message promis, synchrone asynchrone

J'ai besoin d'aide avec mon code. Je suis nouveau sur Node.js et j'ai beaucoup de difficulté avec cela.

Ce que j'essaie de faire:

1) Extraire un fichier .txt avec les produits Amazon (ASIN);

2) Récupérez tous les produits en utilisant le package Amazon-product-api ;

3) Enregistrez chaque produit dans un fichier .json.

Mon code ne fonctionne pas. Je pense que je me suis trompé avec ce truc asynchrone-synchrone - aidez-moi!

var Amazon = require('Amazon-product-api');
var fs = require('fs');

var client = Amazon.createClient({
    awsId: "XXX",
    awsSecret: "XXX",
    awsTag: "888"
});

var array = fs.readFileSync('./test.txt').toString().split('\n');
for (var i = 1; i < array.length; i++) {
     var ASIN = array[i];

    return client.itemLookup({
            domain: 'webservices.Amazon.de',
            responseGroup: 'Large',
            idType: 'ASIN',
            itemId: ASIN
        })
        .then(function(results) {
            fs.writeFile(ASIN + '.json', JSON.stringify(results), function(err) {
                if (err) {
                    console.log(err);
                } else {
                    console.log("JSON saved");
                }
            })

            return results;

        }).catch(function(err) {
            console.log(err);
        });
};
40
Markus Schmidlich

À partir de 2019 ...

... la bonne réponse consiste à utiliser async/wait avec le module natif fs de promesses inclus dans le noeud Effectuez une mise à niveau vers Node.js 10 ou 11 (déjà pris en charge par les principaux fournisseurs de cloud) et procédez comme suit:

const fs = require('fs').promises;

// This must run inside a function marked `async`:
const file = await fs.readFile('filename.txt', 'utf8');
await fs.writeFile('filename.txt', 'test');

N'utilisez pas de packages tiers et n'écrivez pas vos propres wrappers, ce n'est plus nécessaire.

N'est plus expérimental

Avant Node 11.14.0, vous recevrez tout de même un avertissement sur le fait que cette fonctionnalité est expérimentale, mais cela fonctionne très bien et c'est la voie à suivre à l'avenir. Puisque 11.14.0, la fonctionnalité n’est plus expérimentale et prête pour la production.

Et si je préfère import au lieu de require?

Cela fonctionne aussi - mais seulement dans les versions de Node.js où cette fonctionnalité n’est pas marquée comme expérimentale.

import { promises as fs } from 'fs';

(async () => {
    await fs.writeFile('./test.txt', 'test', 'utf8');
})();
63
K48

Parce que fs.writefile Est un rappel asynchrone traditionnel - vous devez suivre la spécification de la promesse et renvoyer une nouvelle promesse qui l'enveloppe avec un gestionnaire de résolution et de rejet comme suit:

return new Promise(function(resolve, reject) {
    fs.writeFile("<filename.type>", data, '<file-encoding>', function(err) {
        if (err) reject(err);
        else resolve(data);
    });
});

Donc, dans votre code, vous l'utiliseriez comme si juste après votre appel à .then()

 .then(function(results) {
    return new Promise(function(resolve, reject) {
            fs.writeFile(ASIN + '.json', JSON.stringify(results), function(err) {
               if (err) reject(err);
               else resolve(data);
            });
    });
  }).then(function(results) {
       console.log("results here: " + results)
  }).catch(function(err) {
       console.log("error here: " + err);
  });
46
AntonB

dire

const util = require('util')
const fs_writeFile = util.promisify(fs.writeFile)

https://nodejs.org/api/util.html#util_util_promisify_original

c'est moins sujet aux bugs que la réponse la plus votée

43
amara

Enfin, la dernière version de node.js v10.3.0 a pris en charge de manière native les promesses de fs.

const fsPromises = require('fs').promises; // or require('fs/promises') in v10.0.0
fsPromises.writeFile(ASIN + '.json', JSON.stringify(results))
  .then(() => {
    console.log('JSON saved');
  })
  .catch(er => {
    console.log(er);
  });

Vous pouvez consulter la documentation officielle pour plus de détails. https://nodejs.org/api/fs.html#fs_fs_promises_api

8
Lewis

Mise à jour septembre 2017: fs-promise a été déconseillé en faveur de fs-extra .


Je ne l'ai pas utilisé, mais vous pourriez regarder dans fs-promise . C'est un module de nœud qui:

Proxie toutes les méthodes f asynchrones les exposant comme promesses/promesses compatibles A + (quand, Q, etc.). Transmet toutes les méthodes de synchronisation en tant que valeurs.

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

const fs_writeFile = util.promisify(fs.writeFile)

fs_writeFile('message.txt', 'Hello Node.js')
    .catch((error) => {
        console.log(error)
    });
2
Saeed Zarinfam

Utilisez fs.writeFileSync dans le bloc try/catch comme ci-dessous.

`var fs = require('fs');
 try {
     const file = fs.writeFileSync(ASIN + '.json', JSON.stringify(results))
     console.log("JSON saved");
     return results;
 } catch (error) {
   console.log(err);
  }`
0
Rahul Sadaphal