请注意 - 这不是关于
async/await
与 .then
的通用 Javascript 问题。如果你对此感到好奇,请看这里:使用 async / wait 与 Promise 的区别?.
这是一个关于在以下情况下使用这两种方法中的任何一种时呈现常见已知边缘情况的问题: 1/ useEffect,2/ 在该 useEffect 中使用 setState,以及 3/特别是在 useEffect 中执行
fetch
时。
这两种方法中的哪一种能够更好地处理常见的边缘情况?
我更愿意 1/ 通过使用更好地处理这些边缘情况的方法来使代码面向未来,2/ 了解常见的边缘情况以了解要考虑哪些情况。
谢谢!
// Method 1
useEffect(() => {
const response = fetch('/api/tacos', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => response.json())
.then(({ data }) => {
console.log('Success:', data);
setTacosArray(() => data);
})
.catch((error) => {
console.error('Error:', error);
});
}, []);
//Method 2
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('/api/tacos', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
const { data } = await response.json();
console.log('Success:', data);
setTacosArray(() => data);
} catch (error) {
console.error('error', error);
}
};
fetchData();
}, []);
在您的代码中,您想要考虑的一种非常常见的情况是需要检查
response.ok
(如果您想获得更详细的信息,还可能包括其他响应代码),然后如果您没有得到response.ok
。
我在下面的代码片段中处理了它,正如您所看到的,链接的
.then
语句将错误语句保留在链的特定“步骤”内。在 async/await
中,检查/响应处理位于主 try
块内。正如您从代码中看到的,这些边缘情况的处理非常相似,最终这将成为一个偏好问题。
// Method 1
useEffect(() => {
const response = fetch('/api/tacos', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
})
.then((response) =>{
// ** CHECK AND HANDLE VARIOUS RESPONSES
if (response.ok) {
return response.json();
} else {
throw new Error('Response NOT okay');}
})
.then(({ data }) => {
console.log('Success:', data);
setTacosArray(() => data);
})
.catch((error) => {
console.error('Error:', error);
});
}, []);
//Method 2
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('/api/tacos', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
// ** CHECK AND HANDLE VARIOUS RESPONSES
if (response.ok) {
const { data } = await response.json();
console.log('Success:', data);
setTacosArray(() => data);
} else {
console.log('Response NOT okay')
}
} catch (error) {
console.error('error', error);
}
};
但是,这些类型的问题可能并不是数据获取可能出现的副作用或问题的总体情况。
大多数 Web 框架在获取/更新数据方面并不是很固执,React 就是其中之一。 NextJS 更加固执己见,多年来变得更加固执己见......它有库
swr
,创建了各种方法,包括 getStaticProps
、getServerSideProps
、Incremental Static Regeneration
,每个方法都有自己的缓存和检索机制,并且在NextJSv13.4+ 对路由系统进行了彻底修改,转而使用核心 WebAPI res/req
对象而不是 res/req
节点对象,并全面引入了各种默认缓存机制。
这里的元点是......您询问了链接
.this
语句与 async/await
的问题,以找出随着应用程序变得更加复杂,未来可能出现的问题以及如何“面向未来”代码。好吧,简短的回答是,无论采用哪种方式,出现的任何问题都可以使用 .then
或 async/await
进行类似处理。
现在,从你的问题中,我认为你试图了解这里存在的更大问题。这些问题超出了
useEffect
/fetch
/.then
与 async/await
的范围,但它与客户端和服务器之间的数据同步有关,这本质上是您的代码处理的问题。 (以下内容摘自 TanStack Query AKA React Query 文档。)。客户端状态和服务器状态是不同的。大多数语句管理库可以很好地处理本地状态,但不能很好地处理异步/服务器状态。这是由于以下原因。服务器状态:
- 远程保存在您无法控制或拥有的位置
- 需要异步 API 来获取和更新
- 意味着共享所有权,其他人可以在您不知情的情况下进行更改
- 如果您不小心,您的应用程序可能会“过时”
然后客户端状态和服务器状态之间的同步会带来这些问题:
- 缓存...(可能是编程中最难做的事情)
- 将对同一数据的多个请求进行重复数据删除到单个请求中
- 在后台更新“过时”数据
- 了解数据何时“过时”
- 尽快反映数据更新
- 分页和延迟加载数据等性能优化
- 管理服务器状态的内存和垃圾收集
- 通过结构共享来记忆查询结果
长话短说,您在问题中询问的任何一种方法(
.then
vs async/await
)都适合您问题中代码指定的操作。
当您想要进行更多优化、处理分页之类的事情以及对自动更新有更多控制......那么您可以转向像 TanStack Query 这样的库。