fs.writeFile dans une promesse, asynchrone-synchrone trucs

j'ai besoin d'aide avec mon code. Je suis nouveau à nodejs et j'ai beaucoup de problèmes avec ça. Ce que j'essaie de faire:

  • 1)chercher un .txt avec les produits Amazon(ASIN)
  • 2)extraction de tous les produits.amazon-produit-api paquet

  • 3)enregistrer chaque produit dans un .fichier json

Mon code ne fonctionne pas. Je pense que j'ai foiré avec ce truc asynchrone-synchrone - aide 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);
        });
};
20
demandé sur Markus Schmidlich 2015-08-13 05:04:39

7 réponses

Parce que fs.writefile est un rappel asynchrone traditionnel - vous devez suivre la spécification promise et retourner une nouvelle promesse enveloppant avec un gestionnaire de résolution et de rejet comme ceci:

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

dans votre code, vous l'utilisez comme une sorte 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);
  });
35
répondu AntonB 2016-08-08 17:10:11

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

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

ceci est moins sujet aux bogues que la réponse la plus votée

27
répondu amara 2017-11-18 00:35:12

Enfin, le dernier nœud.js release v10.3.0 a nativement soutenu les promesses de la SV.

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

5
répondu Lewis 2018-06-03 04:53:58

mise à JourSeptembre 2017:fs-promise a été déprécié en faveur de fs-extra.


je ne l'ai pas utilisé, mais vous pouvez regarder dans fs-promesse. C'est un module de noeud qui:

mandataires toutes les méthodes de fs async les exposant comme compatibles Promises/A+ promesses (quand, Q, etc). Passe toutes les méthodes de synchronisation à travers les valeurs as.

4
répondu rouan 2017-09-26 13:33:16

à partir de 2018...

...la bonne réponse est d'utiliser async / wait avec le natif fs module. Mise à niveau du Nœud.js 10 (déjà pris en charge par les principaux fournisseurs de cloud) et faites ceci:

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 paquets tiers et n'écrivez pas vos propres emballages, ce n'est plus nécessaire.

3
répondu K48 2018-08-30 09:56:03
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
répondu Saeed Zarinfam 2018-05-23 18:20:38

facile à utiliser asynchrone convertir tous rappel de la promesse utiliser une bibliothèque comme "bluebird" .

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

Essayez la solution avec la promesse (bluebird)

var amazon = require('amazon-product-api');
var fs = require('fs');
var Promise = require('bluebird');

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


var array = fs.readFileSync('./test.txt').toString().split('\n');
Promise.map(array, function (ASIN) {
    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);
    });
});
-1
répondu trquoccuong 2015-08-13 02:34:27