Ho il seguente programma: io uso genny.js per gestire il controllo di flusso asincrono - ho provato lo stesso con suspend.js - errore simile.Perché il mio iteratore è di nuovo avanzato?
Sto usando l'API nodejs di stripe.
La mia funzione di iteratore sembra essere chiamata due volte - che causa un errore - e non capisco perché viene chiamata due volte. Deve essere un semplice trucco mentale che non vedo.
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')
})
L'uscita della console è:
> 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
Ora, se sostituisco fetchList con la seguente funzione funziona benissimo:
fetchList = genny.fn(function* (done) {
console.log('before doTimeout')
console.log('1sec break ...')
yield setTimeout(done(), 1000);
console.log('after doTimeout')
return []
})
L'uscita della console è:
> node --harmony genny.js
before run
Before fetchCharges
before doTimeout
1sec break ...
after doTimeout
After fetchCharges - found 0
after run
Per illustrare ulteriormente il fatto che il metodo next() di itertor viene chiamato due volte - ho un'altra versione (non funzionante) del programma.
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')
})
Ed è uscita della console è qui:
> node --harmony genny.js
before run
Before fetchCharges
before fetchList
after fetchList
callback
callback
E 'strano - e io non capisco. Può qualcuno più intelligente di me, per favore, spiegami.
UPDATE
ho cambiato il codice per chiamare i metodi della banda senza un callback o la funzione iteratore ripresa. E ora funziona. MA - curiosamente - guarda la console ai "risultati". Non capisco perché. Quindi ora non chiama la funzione next() di nexter dell'erogatore di fetch() "ma non vedo dove viene chiamata anche una volta !?
var results = yield stripe.charges.list()
Ecco il programma completo aggiornato.
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')
})
Ciò restituisce
> node --harmony genny.js
Before run {
fetchCharges {
fetchList {
} fetchList
} fetchCharges - found 10
} after run
results
Sei sicuro che 'stripe.charges.list' non chiama più la sua richiamata? – Bergi
Controlla se i risultati di 'yield stripe.charges.list (...)' hanno effettivamente senso (cioè se hanno effettivamente una matrice 'data'). – robertklep
Ho aggiornato la domanda con il codice dove non ho nemmeno fornito una funzione callback o resume() alla chiamata stripe - e ora funziona. Non riesco a dare un senso a questo però. Ho sostituito brevemente la funzione resume() che ho passato come richiamata alla chiamata stripe con una funzione di callback ed è stata chiamata solo una volta (forse perché non ho fatto avanzare l'iteratore dopo questo?) – Joerg