Graphql Apollo服务器订阅无法识别异步Iterable
我对Apollo GraphQL的订阅有意见。尝试启动订阅时,我得到的回报是:Graphql Apollo服务器订阅无法识别异步Iterable,graphql,apollo,publish-subscribe,Graphql,Apollo,Publish Subscribe,我对Apollo GraphQL的订阅有意见。尝试启动订阅时,我得到的回报是: "Subscription field must return Async Iterable. Received: { pubsub: { ee: [EventEmitter], subscriptions: {}, subIdCounter: 0 }, pullQueue: [], pushQueue: [], running: true, allSubscribed: null, eventsArray: [\"
"Subscription field must return Async Iterable. Received: { pubsub: { ee: [EventEmitter], subscriptions: {}, subIdCounter: 0 }, pullQueue: [], pushQueue: [], running: true, allSubscribed: null, eventsArray: [\"H-f_mUvS\"], return: [function return] }"
我已经设置了其他订阅,并且完全可以正常工作-因此我可以确认Web服务器的设置是否正确
我只是好奇以前是否有人碰到过这个问题
PR diff中的源代码(这是一个开源项目):
我不认为这是你发布的公关中特有的问题。如果有订阅按原样运行,我会感到惊讶 如错误所述,
subscribe
函数应返回一个AsyncIterable。由于它返回对createPoller
的调用,createPoller
应该返回一个AsyncIterable。但这个函数是这样的:
export default function createPoller(
func,
pubsub,
interval = 5000, // Poll every 5 seconds
timeout = 3600000 // Kill after 1 hour
) {
// Gernate a random internal topic.
const topic = shortid.generate();
// Create an async iterator. This is what a subscription resolver expects to be returned.
const iterator = pubsub.asyncIterator(topic);
// Wrap the publish function on the pubsub object, pre-populating the topic.
const publish = bind(curry(pubsub.publish, 2)(topic), pubsub);
// Call the function once to get initial dataset.
func(publish);
// Then set up a timer to call the passed function. This is the poller.
const poll = setInterval(partial(func, publish), interval);
// If we are passed a timeout, kill subscription after that interval has passed.
const kill = setTimeout(iterator.return, timeout);
// Create a typical async iterator, but overwrite the return function
// and cancel the timer. The return function gets called by the apollo server
// when a subscription is cancelled.
return {
...iterator,
return: () => {
log.info(`Disconnecting subscription ${topic}`);
clearInterval(poll);
clearTimeout(kill);
return iterator.return();
}
};
}
因此,createPoller
创建了一个AsyncIterable,但随后创建了它的浅层副本并返回该副本graphql订阅
使用iterall
的isacynciiterable
检查是否产生了您看到的错误。由于是可同步的
的方式,浅层拷贝不会飞行。您可以亲自看到这一点:
const { PubSub } = require('graphql-subscriptions')
const { isAsyncIterable } = require('iterall')
const pubSub = new PubSub()
const iterable = pubSub.asyncIterator('test')
const copy = { ...iterable }
console.log(isAsyncIterable(iterable)) // true
console.log(isAsyncIterable(copy)) // false
因此,与其返回浅拷贝,createPoller
应该直接变异return
方法:
export default function createPoller(...) {
...
iterator.return = () => { ... }
return iterator
}
我不认为这是一个特定于你发布的公关的问题。如果有订阅按原样运行,我会感到惊讶 如错误所述,
subscribe
函数应返回一个AsyncIterable。由于它返回对createPoller
的调用,createPoller
应该返回一个AsyncIterable。但这个函数是这样的:
export default function createPoller(
func,
pubsub,
interval = 5000, // Poll every 5 seconds
timeout = 3600000 // Kill after 1 hour
) {
// Gernate a random internal topic.
const topic = shortid.generate();
// Create an async iterator. This is what a subscription resolver expects to be returned.
const iterator = pubsub.asyncIterator(topic);
// Wrap the publish function on the pubsub object, pre-populating the topic.
const publish = bind(curry(pubsub.publish, 2)(topic), pubsub);
// Call the function once to get initial dataset.
func(publish);
// Then set up a timer to call the passed function. This is the poller.
const poll = setInterval(partial(func, publish), interval);
// If we are passed a timeout, kill subscription after that interval has passed.
const kill = setTimeout(iterator.return, timeout);
// Create a typical async iterator, but overwrite the return function
// and cancel the timer. The return function gets called by the apollo server
// when a subscription is cancelled.
return {
...iterator,
return: () => {
log.info(`Disconnecting subscription ${topic}`);
clearInterval(poll);
clearTimeout(kill);
return iterator.return();
}
};
}
因此,createPoller
创建了一个AsyncIterable,但随后创建了它的浅层副本并返回该副本graphql订阅
使用iterall
的isacynciiterable
检查是否产生了您看到的错误。由于是可同步的
的方式,浅层拷贝不会飞行。您可以亲自看到这一点:
const { PubSub } = require('graphql-subscriptions')
const { isAsyncIterable } = require('iterall')
const pubSub = new PubSub()
const iterable = pubSub.asyncIterator('test')
const copy = { ...iterable }
console.log(isAsyncIterable(iterable)) // true
console.log(isAsyncIterable(copy)) // false
因此,与其返回浅拷贝,createPoller
应该直接变异return
方法:
export default function createPoller(...) {
...
iterator.return = () => { ... }
return iterator
}
你能用相关的解析器代码更新你的问题吗?我添加了一个链接到我打开的PR,显示了导致问题的相关代码。它非常复杂,如果没有完整的上下文,可能没有完全的意义。你能用相关的解析器代码更新你的问题吗?我添加了一个到PR的链接,我有一个开头,显示了导致问题的相关代码。它非常复杂,如果没有完整的背景,它可能不完全有意义。非常好的回答,谢谢你花时间来解决这个问题。非常感谢!!非常好的回答,谢谢你花时间来解决这个问题。非常感谢!!