javascript - 有承诺的用户 Apollo GraphQL
问题描述
我正在使用 GraphQL 构建 React 本机应用程序。当应用程序进入前台时,我必须在收到来自本机层的事件后进行数据调用。
const eventEmitter = new NativeEventEmitter(NativeModules.EventEmitter)
if (eventEmitter.listeners(Constants.callBacks.NativeSideEventReceived).length === 0) {
eventEmitter.addListener(Constants.callBacks.NativeSideEventReceived, (linearIngressData) => {
const {data, error} = useQuery(CONTENT, {
variables: {
deviceLocale,
contentId,
contentType: Json
},
skip: shouldSkip
})
})
}
问题是,我不能在事件处理程序中使用 useQuery,因为我必须在反应组件中使用 useQuery。
一旦数据可用,我就必须调度一些事件。
const dispatch = useContext(DispatchContext)
if (data) {
dispatch({
type: '_CHANGE',
content: data.content
})
}
我如何使用带有 GQL 的 promise 对象来确保数据可用。如果我在数据可用之前收到NativeSideEventReceived,那么我必须等到我有可用的响应来调度状态事件。
我不能使用 useQuery 的 onComplete 函数,因为要使用 useQuery,我已将其移至功能组件,但是一旦我收到事件,则只需调度该事件。使用 onComplete 将无法保证在接收到事件NativeSideEventReceived后将调用 onComplete 。
谢谢
解决方案
作为 Vue 用户,我创建了这个可组合的小函数,以便拥有 apollo API 的承诺版本。
import { ApolloQueryResult, OperationVariables } from '@apollo/client';
import { useQuery } from '@vue/apollo-composable';
import { DocumentParameter, VariablesParameter } from '@vue/apollo-composable/dist/useQuery';
import { ref } from 'vue';
// promisification of the apollo query
export function useApolloQuery<TResult = any, TVariables extends OperationVariables = OperationVariables>(document: DocumentParameter<TResult, TVariables>, variables: () => VariablesParameter<TVariables>) {
const enableLoginQuery = ref(false);
const { onResult, loading: queryLoading, onError } = useQuery(
document,
variables,
() => ({
enabled: enableLoginQuery.value,
notifyOnNetworkStatusChange: false
}));
const apolloQuery = () => new Promise<ApolloQueryResult<TResult>>((resolve, reject) => {
console.log('calling query apollo');
enableLoginQuery.value = true;
onResult(res => {
if (!res.loading) {
enableLoginQuery.value = false;
if (!res.data) {
reject('no data');
}
resolve(res);
}
});
onError(err => {
enableLoginQuery.value = false;
console.error(err)
reject(err);
});
});
return {
apolloQuery,
queryLoading
};
}
在示例查询中,您可以像这样使用它:
import {useApolloQuery} from '... wherever that is';
const { apolloQuery } = useApolloQuery(UserQueryDoc, () => ({
username: form.value.username,
otherVars: 'other sample var'
}));
const res = await apolloQuery();
全部完全打字。我使用 graphql-tools 来生成类型。
推荐阅读
- node.js - nodemailer 中的“TypeError:无法读取未定义的属性‘响应’”
- python-3.x - 从python中的字符串中删除特殊字符
- python - keras:98% 的准确率,但 NN 总是预测相同。可能是什么原因?
- ios - 试图使 UIButton 成为一个圆圈
- apache-camel - Apache Camel:使用其多参数构造函数实例化一个类
- swift - 在 SwiftUI 中的兄弟姐妹之间从父级共享状态
- android - Poco C++ 安卓 JNI
- java - 查找第一个元素大于或等于最后一个元素且子数组大小等于 X 的子数组
- java - 无效的方法声明需要返回类型,Java 控制器方法
- python - 如何获取当前的“包”名称?(设置.py)