英文:
Under which conditions is the AbortSignal in the TanStack useQuery function undefined?
问题
TanStack React Query文档(https://tanstack.com/query/v4/docs/react/guides/query-cancellation)解释了queryFn
属性如何接收一个带有signal
属性的对象,该属性可用于取消查询,就像这个示例中一样。
const query = useQuery({
queryKey: ['todos'],
queryFn: async ({ signal }) => {
const todosResponse = await fetch('/todos', {
signal,
})
const todos = await todosResponse.json()
const todoDetails = todos.map(async ({ details }) => {
const response = await fetch(details, {
signal,
})
return response.json()
})
return Promise.all(todoDetails)
},
})
问题是,使用TypeScript时,这个signal
属性的类型是AbortSignal | undefined
。根据我正在使用的API,不得不条件性地检查signal
是否已设置会给代码增加很多复杂性,因此知道在哪些情况下signal
对象未定义将非常有帮助。有任何想法将不胜感激。
英文:
The documentation of TanStack React Query (https://tanstack.com/query/v4/docs/react/guides/query-cancellation) explains how the queryFn
property can receive an object with a signal
property, which can be used to cancel a query, like in this example.
const query = useQuery({
queryKey: ['todos'],
queryFn: async ({ signal }) => {
const todosResponse = await fetch('/todos', {
signal,
})
const todos = await todosResponse.json()
const todoDetails = todos.map(async ({ details }) => {
const response = await fetch(details, {
signal,
})
return response.json()
})
return Promise.all(todoDetails)
},
})
The problem is that, with TypeScript, this signal property is type as AbortSignal | undefined
. With the API that I am using, having to conditionally check if the signal
is set adds a lot of complexity to the code so it would be very helpful to know under which conditions this signal
object is not defined. Any ideas would be much appreciated.
答案1
得分: 1
react-query v4.29.11
如果AbortController
类存在,则会存在signal
。让我们看一下源代码:
signal
属性是通过addSignalProperty()
函数添加到查询函数上下文中的,如下所示:
const addSignalProperty = (object: unknown) => {
Object.defineProperty(object, 'signal', {
enumerable: true,
get: () => {
if (abortController) {
this.abortSignalConsumed = true
return abortController.signal
}
return undefined
},
})
}
addSignalProperty(queryFnContext)
通过getAbortController()
函数获取abortController
:
export function getAbortController(): AbortController | undefined {
if (typeof AbortController === 'function') {
return new AbortController()
}
return
}
这就是为什么signal
属性的TS类型是:AbortSignal | undefined
。
官方文档也提到了这一点。
AbortController
API 在大多数运行时环境中都可用,但如果运行时环境不支持它,那么查询函数将接收到undefined
。如果愿意,您可以选择使用几种可用的方法来进行AbortController
API 的polyfill。
英文:
react-query v4.29.11
The signal
will exist if the AbortController
class exists. Let's take a look at the source code:
The signal
property is added to the query function context by addSignalProperty()
function, see below:
const addSignalProperty = (object: unknown) => {
Object.defineProperty(object, 'signal', {
enumerable: true,
get: () => {
if (abortController) {
this.abortSignalConsumed = true
return abortController.signal
}
return undefined
},
})
}
addSignalProperty(queryFnContext)
The abortController
is got by getAbortController()
function
export function getAbortController(): AbortController | undefined {
if (typeof AbortController === 'function') {
return new AbortController()
}
return
}
That's why the TS type of signal
property is: AbortSignal | undefined
.
The official documentation also mentions it.
> The AbortController
API is available in most runtime environments, but if the runtime environment does not support it then the query function will receive undefined
in its place. You may choose to polyfill the AbortController
API if you wish, there are several available.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论