1 前因后果
今天又是一天努力工作(水群)的一天,突然看到群友在说某依框架垃圾,理由是没有封装请求,还要在代码里写.then
emmmmm.....
在我印象中是有几个后台管理是请求封装成return await xxxx这样的,忘了是ant design pro 还是jeecgboot了,也可能都不是,当初没觉得有啥不好,觉得这样代码执行顺序可控啊。
2 思前想后
不过今天的我已经不是昨天的我了
我当场提出质问:为哈?.then有什么不好
群友:大家不都是async await?
算了上图聊天截图吧!!!
深度不自信性格的我陷入了沉思:同步写法,异步执行
今年有幸耐住性子把前端红宝石书看了一些,刚好有看了await/async 和 Promise,但是记忆有些模糊了。
记得await是会导致同步代码的后续会暂停是肯定的,但是await如果后面还是异步请求呢?很像这个说法,给我整迷糊了一下。脑子里的代码逻辑当时如下:
const a = await fetch() // 发出请求
const b = await fetch() // 发出请求,等待a赋值好,b再赋值
聊天记录里能够看出我的大脑告诉我是20s,不自信的我被引导成await完还是5s。
本着实践出真知(先检查自己的想法是否正确,再有底气)的敲起了demo
3 实践
demo1 await
async function getData(num: number) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(num)
}, 2000)
})
}
const App = () => {
const [value1, setValue1] = useState(0)
const [value2, setValue2] = useState(0)
const [value3, setValue3] = useState(0)
const [value4, setValue4] = useState(0)
const fetchData = useCallback(async () => {
try {
const beginTime = Date.now()
console.log('beginTime', beginTime)
const data1 = await getData(1)
const data2 = await getData(2)
const data3 = await getData(3)
const data4 = await getData(4)
setValue1(data1);
setValue2(data2);
setValue3(data3);
setValue4(data4);
const endTime = Date.now()
console.log('endTIme:', endTime)
console.log(endTime - beginTime)
} catch (error) {
console.error('Error fetching data:', error);
}
}, []);
useEffect(() => {
fetchData();
}, [fetchData]);
return (
<div>
{value1}
{value2}
{value3}
{value4}
</div>
);
};
demo2 then
async function getData(num: number) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(num)
}, 2000)
})
}
const App = () => {
const [value1, setValue1] = useState(0)
const [value2, setValue2] = useState(0)
const [value3, setValue3] = useState(0)
const [value4, setValue4] = useState(0)
const count = useRef(0)
const beginTime = useRef()
const endTime = useRef()
const compute = useCallback(() => {
count.current += 1
if (count.current === 4) {
endTime.current = Date.now()
console.log('endTIme:', endTime)
console.log(endTime.current - beginTime.current)
}
}, [])
useEffect(() => {
beginTime.current = Date.now()
console.log('beginTime', beginTime)
getData(1).then(data => {
setValue1(data)
compute()
})
getData(2).then(data => {
setValue2(data)
compute()
})
getData(3).then(data => {
setValue3(data)
compute()
})
getData(4).then(data => {
setValue4(data)
compute()
})
}, []);
return (
<div>
{value1}
{value2}
{value3}
{value4}
</div>
);
};
结论
- 在一个只有表格的页面的情况下 await和then没差别,就一个请求
- 在多个请求的情况下,渲染独立多个地方的时候,明显then更好
当然也是可以优化的,配合Promise
try {
const results = await Promise.all([
getData(1),
getData(2),
getData(3),
getData(4)
]);
setValue1(results[0]);
setValue2(results[1]);
setValue3(results[2]);
setValue4(results[3]);
} catch (error) {
console.error('Error fetching data:', error);
}
4 继续工作(摸x)
也不知道怎么的我就开启了回忆,(大脑的结构真是复杂),想到了回调地狱....
曾几何时我也是个很菜很菜很菜的菜逼,当时写then的时候是这么写的,所以曾经一味的觉得await永远的神,这么封装很牛逼。
getData(1).then(data => {
setValue1(data)
compute()
getData(2).then(data => {
setValue2(data)
compute()
getData(3).then(data => {
setValue3(data)
compute()
getData(4).then(data => {
setValue4(data)
compute()
})
})
})
})
哈哈哈,看到这个代码笑出了声,不是说promise为了解决回调地狱吗,我用了呀,但是这不还是地狱吗?
也许现在也还有人这么写,其实我在写两层嵌套的时候也还是这么写,很顺手!!!!!
但其实应该解决的写法是
await/async 写法
其实就是之前demo敲的,异步变同步,这也是我认为await/async的核心作用(可能异步变同步这个说法有点问题,想不到什么好的描述)
try {
const data1 = await getData(1)
const data2 = await getData(2)
const data3 = await getData(3)
const data4 = await getData(4)
setValue1(data1);
setValue2(data2);
setValue3(data3);
setValue4(data4);
} catch (error) {
console.error('Error fetching data:', error);
}
then写法
这样写才能说是解决回调地狱,让异步看起来像同步代码
getData(1).then(data1 => {
setValue1(data1)
compute()
return getData(2)
}).then(data2 => {
setValue2(data2)
compute()
return getData(3)
}).then(data3 => {
setValue3(data3)
compute()
return getData(4)
}).then(data4 => {
setValue4(data4)
compute()
}).catch(err => {
console.error('Error fetching data:', err);
})
两种的错误拦截
catch在某一个then出现错误都会触发,如果有需要知道是哪一个产生的报错,我目前是没有什么更优解决,只能说像这样
getData(1).then(data1 => {
setValue1(data1)
compute()
return getData(2)
}).catch(err => {
console.error('Error fetching data:', err);
}).then(data2 => {
setValue2(data2)
compute()
return getData(3)
}).catch(err => {
console.error('Error fetching data:', err);
}).then(data3 => {
setValue3(data3)
compute()
return getData(4)
}).catch(err => {
console.error('Error fetching data:', err);
}).then(data4 => {
setValue4(data4)
compute()
}).catch(err => {
console.error('Error fetching data:', err);
})
async/await就比较好看一点
try {
const data1 = await getData(1).catch(err => { console.error('Error fetching data1:', err); })
const data2 = await getData(2).catch(err => { console.error('Error fetching data2:', err); })
const data3 = await getData(3).catch(err => { console.error('Error fetching data3:', err); })
const data4 = await getData(4).catch(err => { console.error('Error fetching data4:', err); })
setValue1(data1);
setValue2(data2);
setValue3(data3);
setValue4(data4);
} catch (error) {
console.error('Error fetching data:', error);
}
不是什么技术文章,就记录一下脑子运转的过程,和demo敲出来的结论,下次可以不用再敲一遍