write trabajar promesas nodejs node example encadenamiento con asincrono node.js asynchronous amazon sync amazon-product-api

node.js - trabajar - fs.writeFile en una promesa, asíncrono-síncrono cosas



trabajar con promesas javascript (7)

Necesito un poco de ayuda con mi código. Soy nuevo en nodejs y tengo muchos problemas con eso. Lo que estoy tratando de hacer:

  • 1) obtener un .txt con los productos de Amazon (ASIN)
  • 2) obtener todos los productos con el paquete amazon-product-api

  • 3) guardar cada producto en un archivo .json

Mi código no funciona. Creo que me equivoqué con estas cosas asíncronas sincrónicas. ¡Ayúdame!

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


A partir de 2018 ...

... la respuesta correcta es usar async / await con el módulo fs nativo. Actualice a Node.js 10 (que ya es compatible con los principales proveedores de la nube) y haga esto:

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

No utilice paquetes de terceros y no escriba sus propios envoltorios, eso ya no es necesario.

A partir del Nodo 11.1.0 , recibirá una advertencia de que esta función es experimental, pero funciona bien y es el camino a seguir en el futuro.


Debido a que fs.writefile es una devolución de llamada asíncrona tradicional, debe seguir la especificación de promesa y devolver una nueva promesa envolviéndola con un controlador de resolución y rechazo, como por ejemplo

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

Así que en tu código lo .then() así justo después de tu llamada a .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); });


Finalmente, la última versión de node.js v10.3.0 ha soportado las promesas de forma nativa.

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

Puedes consultar la documentación oficial para más detalles. https://nodejs.org/api/fs.html#fs_fs_promises_api


Para que sea fácil de usar, convierta de forma asíncrona todas las devoluciones de llamada a la promesa de usar alguna biblioteca como "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); });

Probar la solución con promesa (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); }); });



Actualización de septiembre de 2017 : fs-promise ha sido desaprobada en favor de fs-extra .

No lo he usado, pero podrías mirar fs-promise . Es un módulo de nodo que:

Proxies todos los métodos fs asíncronos exponiéndolos como promesas / promesas compatibles con A + (cuándo, Q, etc.). Pasa todos los métodos de sincronización a través de como valores.


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