解决异步传染性问题
发表于:2023-11-14 |

前言

不知道大家有没有遇到过这种情况,就是当我们写一个异步的时候,会将其他方法同样污染成为异步方法,今天和大家分享一个解决异步传染的方法

问题情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>异步传染性</title>
</head>
<script>
async function fetchData(){
return await fetch('https://cnodejs.org/api/v1/topics?page=1&limit=10')
}
async function m1(){
const data=await fetchData()
return data.json()
}
async function main(){
const data=await m1()
console.log(data)
}
main();
</script>
<body>

</body>
</html>

我就写了以上这样的代码,此时如果我们想要获取请求得到的值,就必须把函数给污染了,所有的方法都变成了异步方法,现在的需求是我不想要把方法都变成异步方法,我只想要获取到请求的值,该怎么办呢?

实现逻辑

其实实现这个也很简单,我们只需要执行两次这个main方法,第一次的时候存储缓存,抛出错误,然后我们检测到错误就重新执行这个方法,然后取值我们用缓存的值就可以了,下面我们来看一下代码

将原有的异步改为同步

1
2
3
4
5
6
7
8
9
10
11
function fetchData(){
return fetch('https://cnodejs.org/api/v1/topics?page=1&limit=10')
}
function m1(){
const data=fetchData()
return data
}
function main(){
const data=m1()
console.log(data)
}

实现代码

核心逻辑我都备注在代码里面了,主要实现逻辑就是用了我上面说的实现逻辑,此时我们的控制台,依旧是可以看到我们的请求数据的,但是我们的方法没有被污染,这样就可以解决异步传染性的问题了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
function run(func){
// 定义缓存
let cache={
status:'pending',
result:null
}
const oldFetch=window.fetch
window.fetch=function(...args){
// 有缓存直接返回
if(cache.status==='fulfilled'){
return cache.result
}
// 有错误抛出
else if(cache.status==='rejected'){
throw cache.result
}
// 发送真实请求
// 保存数据
const prom=oldFetch(...args).then(response=>response.json()).then(res=>{
cache.status='fulfilled'
cache.result=res
}).catch(err=>{
cache.status='rejected'
cache.result=err
})
// pending情况抛错promise
throw prom
}
try{
func()
}
catch(err){
// 等待promise执行完毕调用func方法
if(err instanceof Promise){
err.then(func,func).finally(()=>window.fetch=oldFetch)
}
}
}

run(main)

处理污染异步解决

结语

本篇文章就到这里了,更多内容敬请期待~

上一篇:
【可视化学习】53-元宇宙未来智慧城(二)
下一篇:
【可视化学习】52-元宇宙未来智慧城(一)