ben*_*nwl 2 javascript reactjs fetch-api
我目前有一个坐标列表,我用它来获取附近的徒步旅行。假设我将列表状态更新为新坐标,但先前坐标的提取请求未完成 - 如何取消对先前坐标发出的所有提取请求,而仅根据新坐标调用新的提取请求?
我尝试实现,AbortController但它可能不起作用,因为它没有取消“批量”的获取请求,而只是取消单个获取请求。我的代码如下:
let abortController = new AbortController();
const getNearbyHikes = async (coordinates) => {
abortController.abort();
abortController = new AbortController();
for (const coord of coordinates) {
if (coord) {
try {
const { lat, lng } = cord.coordinates
const response = await fetch(
'http://localhost:5000/category/' + lat + "/" + lng + '/' + searchCategory,
{signal: abortController.signal}
)
const result = await response.json();
setHikes((prevState) => [...prevState, ...result.businesses])
} catch (error) {
if(error.name === 'AbortError'){
return;
}
throw error
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
另外,我想在获得加息时更新我的用户界面,这样我的网络应用程序看起来并不很慢,所以我避免使用Promise.all. 非常感谢任何建议或帮助。
取消的主要问题是您错误地提供了信号fetch。您提供信号作为第二个参数,但fetch需要一个带有signal属性的“init”对象。
不过,正如 @Keith 指出的那样,您当前的代码一次只能进行一个调用。这会起作用,但您可能会从并行进行调用中受益。
像这样的东西:
const getOneResult = async ({ lat, lng }, signal) => {
try {
const response = await fetch(
"http://localhost:5000/category/" +
lat +
"/" +
lng +
"/" +
searchCategory, // *** Where does this come from?
{ signal }
);
if (signal && signal.aborted) {
throw new DOMException("Request cancelled", "AbortError");
}
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
return response.json();
} catch (error) {
if (error.name === "AbortError") {
return null;
}
}
};
const getNearbyHikes = async (coordinates, signal) => {
controller.abort();
controller = new AbortController();
const results = await Promise.all(
coordinates.map((coord) => getOneResult(coord.coordinates, signal))
);
if (signal && signal.aborted) {
return;
}
const businesses = [];
for (const result of results) {
businesses.push(...result.businesses);
}
setHikes((prevState) => [...prevState, ...businesses]);
};
Run Code Online (Sandbox Code Playgroud)
最后,我会让调用者提供信号,而不是对所有调用使用全局信号getHikes:
const getOneResult = async ({ lat, lng }, signal) => {
try {
const response = await fetch(
"http://localhost:5000/category/" +
lat +
"/" +
lng +
"/" +
searchCategory, // *** Where does this come from?
{ signal }
);
if (signal && signal.aborted) {
throw new DOMException("Request cancelled", "AbortError");
}
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
return response.json();
} catch (error) {
if (error.name === "AbortError") {
return null;
}
}
};
let controller = new AbortController();
const getNearbyHikes = async (coordinates) => {
controller.abort();
controller = new AbortController();
const results = await Promise.all(
coordinates.map((coord) => getOneResult(coord.coordinates, signal))
);
if (signal && signal.aborted) {
return;
}
const businesses = [];
for (const result of results) {
businesses.push(...result.businesses);
}
setHikes((prevState) => [...prevState, ...businesses]);
};
Run Code Online (Sandbox Code Playgroud)
然后调用者控制中止请求。但前者可能适合您的用例。
response.ok旁注:您会看到我在其中添加了一张支票。您的代码假设由于fetch承诺已履行,HTTP 调用有效,但不幸的是,这是 API 中的一个枪:它仅在网络fetch故障时拒绝其承诺,而不是在 HTTP 失败时拒绝。您必须明确检查后者。
| 归档时间: |
|
| 查看次数: |
1828 次 |
| 最近记录: |