Aşağıdaki programı kullanıyorum - asenkronize akış denetimini işlemek için genny.js kullanıyorum - suspend.js ile aynı şeyi denedim - benzer bir hata.Yineleyicim neden tekrar geliştiriliyor?
Stripe nodejs API'sini kullanıyorum.
Yineleyici işlevim iki kez çağrılıyor gibi görünüyor - bu bir hataya neden oluyor - ve neden iki kez çağrıldığını anlamıyorum. Görmediğim basit bir zihin numarası olmalı.
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')
})
konsol çıktısı:
> 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
Şimdi, aşağıdaki işlevi ile fetchList yerine eğer iyi çalışır:
fetchList = genny.fn(function* (done) {
console.log('before doTimeout')
console.log('1sec break ...')
yield setTimeout(done(), 1000);
console.log('after doTimeout')
return []
})
konsol çıktısı:
> node --harmony genny.js
before run
Before fetchCharges
before doTimeout
1sec break ...
after doTimeout
After fetchCharges - found 0
after run
Gerçeği daha fazla göstermek için iterörün next() yöntemi iki kez çağrılır - programın başka bir (çalışmayan) sürümü var.
> node --harmony genny.js
before run
Before fetchCharges
before fetchList
after fetchList
callback
callback
Bu garip - ve bunu alamadım:
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')
})
Ve bu konsol çıkış burada. Biri benden daha zeki olabilir lütfen açıklayınız.
GÜNCELLEME
Bir geri arama veya yineleyici özgeçmiş fonksiyonu olmadan şerit yöntemleri çağırmak için kod değişti. Ve şimdi çalışıyor. AMA - merakla - "sonuç" da konsola bakın. Ben neden anlamıyorum. Yani şimdi fetchList yineleyici next() fonksiyonu "ikinci kez" diyoruz - ama bir kez bile çağrılır nerede görmüyorum !?
var results = yield stripe.charges.list()
Güncelleştirilmiş programın tamamı.
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')
})
Bu, karşılaştığınız sorun asenkronisi için iki yaklaşımın bir karışımı kaynaklanıyor
> node --harmony genny.js
Before run {
fetchCharges {
fetchList {
} fetchList
} fetchCharges - found 10
} after run
results
'stripe.charges.list' dizininin birden çok kez geri çağırılmadığından emin misiniz? – Bergi
Verim stripe.charges.list (...) 'sonuçlarının gerçekten anlamlı olup olmadığını (yani, bir" veri "dizisi varsa) kontrol edin. – robertklep
Soruyu, kod çağrısı için bir geri arama veya resume() işlevi sağlamadığım bir kodla güncelledim - ve şimdi çalışıyor. Bununla ilgili bir fikrim yok. Kısaca, geri arama işlevi ile şerit çağrısı için bir geri çağırma olarak geçen resume() işlevini yerine koydu ve yalnızca bir kez çağrıldı (belki de bundan sonra yineleyici ilerlemediğim için?) – Joerg