消除异步的传染性
什么是异步的传染性
- 异步函数具有传染性 比如一个函数中使用了 fetch 会导致调用他的函数也变成异步的.
如何消除传染性
- 将fetch 变成同步函数.
- 将fetch 返回的数据缓存起来
- 隔离异步函数在 throw 中
消除的过程称为 代数效应:
- 代数效应是一种方法, 可以"隔离函数中的副作用, 从而让函数变为纯函数"。
- 从实现机制角度来说, 代数效应可以看作是一种执行控制, 函数可以在某个需要执行副作用的地方暂停,保存并跳出当前执行栈, 沿调用栈向上找到这个副作用对应的处理函数(handlers), 处理函数执行完毕, 再从之前暂停的地方继续执行。
- react中的Suspense 就是利用了这个原理.
- B站视频
- React中的代数效应
function getData() {
const r = fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
}),
});
console.log(r);
}
function run(func) {
let oldFetch = window.fetch;
let cache = {
value: '',
status: 'pending',
};
window.fetch = function(...args) {
if(cache && cache.status === 'fulfilled') {
return cache.value;
} else if(cache.status === 'rejected') {
throw cache.value;
}else {
const prom = oldFetch(...args).then((res) => {
return res.json();
}).then(res => {
cache.value = res;
cache.status = 'fulfilled';
}).catch(err => {
cache.value = err;
cache.status = 'rejected';
});
throw prom;
}
}
if(func) {
try {
func();
}catch(err) {
if(err instanceof Promise) {
err.then(func, func).finally(() => {
window.fetch = oldFetch;
});
}
}
}
}
run(getData);
```