I have the following program - I use genny.js to handle asynchronous flow control - I tried the same with suspend.js - a similar error.
I am using Stripe nodejs API.
My iterator function seems to be called twice - this causes an error - and I don't understand why it is called twice. It should be a simple trick that I do not see.
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') })
Console output:
> 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
Now, if I replaced fetchList with the following function, it works fine:
fetchList = genny.fn(function* (done) { console.log('before doTimeout') console.log('1sec break ...') yield setTimeout(done(), 1000); console.log('after doTimeout') return [] })
Console output:
> node --harmony genny.js before run Before fetchCharges before doTimeout 1sec break ... after doTimeout After fetchCharges - found 0 after run
To show once again that the itertor next () method is called twice - I have another (non-working) version of the program.
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') })
And he displays the console here:
> node --harmony genny.js before run Before fetchCharges before fetchList after fetchList callback callback
This is strange - and I do not understand. Can someone smarter than me, please explain.
UPDATE
I changed the code to call stripe methods without a callback or the iterator resume function. And now it works. BUT - curious - look at the console for "results." I do not understand why. So now it doesnโt call the fetchList iterator next () function โsecond timeโ, but I donโt see where it is even called once !?
var results = yield stripe.charges.list()
Here's the updated full program.
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') })
It returns
> node --harmony genny.js Before run { fetchCharges { fetchList { } fetchList } fetchCharges - found 10 } after run results