Apollo使用withFilter异步过滤时未向客户端推送事件通知问题
问题原因分析
- graphql-subscriptions 包版本兼容问题:如果你使用的是
v0.5.x及更早版本的graphql-subscriptions,withFilter的第二个参数不支持异步函数,内部不会等待Promise执行完成,会直接将Promise对象当作真值判断,但后续推送逻辑在Promise resolve之前就已经结束,导致即使异步返回true也不会触发客户端推送。你打印的result是true只是异步逻辑执行完成后的输出,此时已经过了推送的时间窗口。 - 返回值不是原始布尔类型:如果
firebaseApi.userHasEntity返回的是Boolean包装对象(比如new Boolean(true))而非原始布尔值true,部分版本的withFilter内部做严格相等判断时会将其判定为非true,导致过滤不通过。 - Apollo Server 订阅上下文过期:如果你使用的是Apollo Server 4+版本,订阅的请求上下文在事件触发后的有效时间很短,异步调用
firebaseApi.userHasEntity的耗时超过上下文有效期后,即使返回true,内部推送逻辑也会因为上下文销毁而终止推送。
验证修复方案
- 升级
graphql-subscriptions到最新稳定版,确保异步过滤器被正确支持 - 把过滤器的返回语句修改为
return !!result,强制转换为原始布尔值,排除返回值类型问题 - 可将用户的实体权限数据提前挂载到订阅初始上下文中,避免过滤阶段再做异步查询,减少耗时
async (payload, variables, context) => { let result = await firebaseApi.userHasEntity( context.user, payload.entityCreated ); console.log(result); return !!result; }
内容的提问来源于stack exchange,提问作者Christo S. Christov
相关产品推荐
相关产品推荐

