update tutorial nodejs node framework español ejemplos actualizar node.js promise generator stripe-payments ecmascript-6

node.js - tutorial - ¿Por qué mi iterador está siendo avanzado nuevamente?



npm install (1)

El problema que está experimentando proviene de una combinación de dos enfoques para la asincronía.

La banda API menciona menciones

Cada método de recursos acepta una devolución de llamada opcional como último argumento.
Además, cada método de recursos devuelve una promesa.

Sin embargo, tanto genny como suspender hacen

Trabajar sin problemas con las convenciones y promesas de devolución de llamada de Node

Y aquí yace tu error: en la línea

var results = yield stripe.charges.list({}, done())

usted usa implícitamente ambos al mismo tiempo. El done() crea una devolución de llamada que se pasa a la banda, pero esa llamada también produce una promesa que se produce, y genny / suspender registrar otra devolución de llamada en él. Esto lleva al Error: callback already called que está observando.

Puede elegir cómo quiere solucionar el problema:

  • no cedas la promesa

    var results = yield void stripe.charges.list({}, done()) // ^^^^

  • no pase una devolución de llamada

    var results = yield stripe.charges.list({})

(Recomendaría este último)

Tengo el siguiente programa - Yo uso genny.js para manejar el control de flujo asíncrono - He intentado lo mismo con suspend.js - error similar.

Estoy usando la API Stripe nodejs.

La función de mi iterador parece ser llamada dos veces, lo que está causando un error, y no entiendo por qué se llama dos veces. Debe ser un simple truco mental que no estoy viendo.

var genny = require(''genny'') genny.longStackSupport = true var stripe = require("stripe")("sk_live_....") fetchCharges = genny.fn(function* (d) { console.log("Before fetchCharges") var charges = yield fetchList(d()) console.log("After fetchCharges - found ", charges.length) return true }) fetchList = genny.fn(function* (done) { console.log("before fetchList") var results = yield stripe.charges.list({}, done()) console.log("after fetchList") return results.data }) genny.run(function* (resume) { console.log(''before run'') yield fetchCharges(resume()) console.log(''after run'') })

La salida de la consola es:

> node --harmony genny.js before run Before fetchCharges before fetchList after fetchList After fetchCharges - found 10 after run /Volumes/dev/ingest/node_modules/genny/index.js:50 else throw e; ^ Error: callback already called at resume (/Volumes/dev/ingest/node_modules/genny/index.js:154:39) at throwAt (/Volumes/dev/ingest/node_modules/genny/index.js:49:30) at resume (/Volumes/dev/ingest/node_modules/genny/index.js:153:28) at tryProcessPending (/Volumes/dev/ingest/node_modules/genny/index.js:41:28) at resume (/Volumes/dev/ingest/node_modules/genny/index.js:164:17) at null._onTimeout (/Volumes/dev/ingest/node_modules/stripe/lib/StripeResource.js:87:34) at Timer.listOnTimeout (timers.js:110:15) From generator: at /Volumes/dev/ingest/genny.js:22:26

Ahora, si reemplazo fetchList con la siguiente función, funciona bien:

fetchList = genny.fn(function* (done) { console.log(''before doTimeout'') console.log(''1sec break ...'') yield setTimeout(done(), 1000); console.log(''after doTimeout'') return [] })

La salida de la consola es:

> node --harmony genny.js before run Before fetchCharges before doTimeout 1sec break ... after doTimeout After fetchCharges - found 0 after run

Para ilustrar aún más el hecho de que el método siguiente del (itertor) se llama dos veces, tengo otra versión (no operativa) del programa.

var genny = require(''genny'') genny.longStackSupport = true var stripe = require("stripe")("sk_live_...") fetchCharges = genny.fn(function* (d) { console.log("Before fetchCharges") var charges = yield fetchList(function(err, cb) { console.log("callback") }) console.log("After fetchCharges - found ", charges.length) return true }) fetchList = genny.fn(function* (done) { console.log("before fetchList") var results = yield stripe.charges.list({}, done()) console.log("after fetchList") return results.data }) genny.run(function* (resume) { console.log(''before run'') yield fetchCharges(resume()) console.log(''after run'') })

Y la salida de la consola está aquí:

> node --harmony genny.js before run Before fetchCharges before fetchList after fetchList callback callback

Es extraño, y no lo entiendo. ¿Puede alguien más listo que yo? Explique por favor.

ACTUALIZAR

He cambiado el código para llamar a los métodos de banda sin devolución de llamada o la función de reanudación del iterador. Y ahora funciona PERO, curiosamente, mira la consola en los "resultados". No entiendo por qué. Así que ahora no llama a la función next () del repetidor fetchList "por segunda vez", ¡pero no veo dónde se llama una vez!

var results = yield stripe.charges.list()

Aquí está el programa completo actualizado.

var genny = require(''genny'') genny.longStackSupport = true var stripe = require("stripe")("sk_live_i6TrEk5lSRM1CmbSZZPsQzKc") fetchCharges = genny.fn(function* (d) { console.log(" fetchCharges {") var charges = yield fetchList(d()) console.log(" } fetchCharges - found ", charges.length) return true }) fetchList = genny.fn(function* (done) { console.log(" fetchList {") var results = yield stripe.charges.list({}, function(err, results) { console.log("results ") }) console.log(" } fetchList") return results.data }) genny.run(function* (resume) { console.log(''Before run {'') yield fetchCharges(resume()) console.log(''} after run'') })

Esto regresa

> node --harmony genny.js Before run { fetchCharges { fetchList { } fetchList } fetchCharges - found 10 } after run results