如何在 React 中使用 promise 进行重构?
How to refactor with promise in React?
Visual Studio 代码建议重构代码以降低复杂性。我不知道 Promise 是什么以及如何重构下面的代码。谁能帮帮我?
const handleLoadInventory = async () => {
try {
const _data = await fetch('http://localhost:4000/api/v1/inventory/', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('token'),
},
})
if (_data.status === 200) {
const data = await _data.json()
if (data.items.length !== 0) {
if (inventoryData.length)
for (let i = 1; i <= Math.ceil(data.items.length / 10); i++) {
pagination.push(i)
}
for (let i = 0; i < 10 && i < data.items.length; i++) {
showData.push(data.items[i])
}
setInventoryData(data.items)
} else {
setZeroAlert(true)
}
} else {
setServerAlert(true)
throw new Error()
}
} catch (err) {
setServerAlert(true)
console.error(err)
}
}
重构是将功能分解成更小单元的艺术。它背后的关键思想是通过使函数变小来使函数“显而易见”,从而使错误也变得明显。除了函数的工作原理之外,您真的不需要了解任何其他知识。
我要提取的第一部分是 fetch
,因为您可能会不止一次地使用它。 Copy/pasting 您的获取代码是 bug-prone。您可能忘记设置它的 content-type 或者您可能忘记包含身份验证令牌。
因此值得把它做成自己的功能,而不仅仅是一段代码:
// This function returns a promise because fetch returns a promise:
function get (url) {
return fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('token'),
},
})
}
接下来是状态代码 200 的处理。您正在使用 if
块。这意味着确保所有获取数据的函数都具有相同的结构。同样,由于 copy/paste 编程,它很容易出错。
由于您正在设置状态并抛出错误,因此您可以在上面的 get()
函数中处理它:
// This function returns a promise because fetch returns a promise:
async function get (url) {
let response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('token'),
},
})
if (response.status !== 200) {
throw new Error('Server response invalid')
}
return response
}
setServerAlert()
将由您的外部 try/catch 块处理,因为我们抛出错误。
现在您的代码已大大简化:
const handleLoadInventory = async () => {
try {
const _data = await get('http://localhost:4000/api/v1/inventory/')
const data = await _data.json()
if (data.items.length !== 0) {
if (inventoryData.length)
for (let i = 1; i <= Math.ceil(data.items.length / 10); i++) {
pagination.push(i)
}
for (let i = 0; i < 10 && i < data.items.length; i++) {
showData.push(data.items[i])
}
setInventoryData(data.items)
} else {
setZeroAlert(true)
}
} catch (err) {
setServerAlert(true)
console.error(err)
}
}
就我个人而言,我什至会把 _data.json()
部分移到 get()
函数中,但我想你明白了。
Visual Studio 代码建议重构代码以降低复杂性。我不知道 Promise 是什么以及如何重构下面的代码。谁能帮帮我?
const handleLoadInventory = async () => {
try {
const _data = await fetch('http://localhost:4000/api/v1/inventory/', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('token'),
},
})
if (_data.status === 200) {
const data = await _data.json()
if (data.items.length !== 0) {
if (inventoryData.length)
for (let i = 1; i <= Math.ceil(data.items.length / 10); i++) {
pagination.push(i)
}
for (let i = 0; i < 10 && i < data.items.length; i++) {
showData.push(data.items[i])
}
setInventoryData(data.items)
} else {
setZeroAlert(true)
}
} else {
setServerAlert(true)
throw new Error()
}
} catch (err) {
setServerAlert(true)
console.error(err)
}
}
重构是将功能分解成更小单元的艺术。它背后的关键思想是通过使函数变小来使函数“显而易见”,从而使错误也变得明显。除了函数的工作原理之外,您真的不需要了解任何其他知识。
我要提取的第一部分是 fetch
,因为您可能会不止一次地使用它。 Copy/pasting 您的获取代码是 bug-prone。您可能忘记设置它的 content-type 或者您可能忘记包含身份验证令牌。
因此值得把它做成自己的功能,而不仅仅是一段代码:
// This function returns a promise because fetch returns a promise:
function get (url) {
return fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('token'),
},
})
}
接下来是状态代码 200 的处理。您正在使用 if
块。这意味着确保所有获取数据的函数都具有相同的结构。同样,由于 copy/paste 编程,它很容易出错。
由于您正在设置状态并抛出错误,因此您可以在上面的 get()
函数中处理它:
// This function returns a promise because fetch returns a promise:
async function get (url) {
let response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + localStorage.getItem('token'),
},
})
if (response.status !== 200) {
throw new Error('Server response invalid')
}
return response
}
setServerAlert()
将由您的外部 try/catch 块处理,因为我们抛出错误。
现在您的代码已大大简化:
const handleLoadInventory = async () => {
try {
const _data = await get('http://localhost:4000/api/v1/inventory/')
const data = await _data.json()
if (data.items.length !== 0) {
if (inventoryData.length)
for (let i = 1; i <= Math.ceil(data.items.length / 10); i++) {
pagination.push(i)
}
for (let i = 0; i < 10 && i < data.items.length; i++) {
showData.push(data.items[i])
}
setInventoryData(data.items)
} else {
setZeroAlert(true)
}
} catch (err) {
setServerAlert(true)
console.error(err)
}
}
就我个人而言,我什至会把 _data.json()
部分移到 get()
函数中,但我想你明白了。