我对Apollo GraphQL的订阅有问题。尝试启动订阅时,我得到以下回报:
"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] }"
我还有其他订阅设置,并且功能完全正常-因此,我可以确认网络服务器设置正确。
我很好奇,是否有人曾经遇到过这个问题。
PR diff中的源代码(这是一个开源项目): https://github.com/astronomer/houston-api/pull/165/files
答案 0 :(得分:0)
我认为这不是您发布的PR所特有的问题。如果有任何订阅按原样工作,我会感到惊讶。
您的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-subscriptions
将iterall
的{{1}}用于产生您所看到的错误的检查。由于isAsyncIterable
works的方式,浅拷贝不会飞行。您可以自己查看:
isAsyncIterable
因此,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