消除异步的传染性
什么是异步的传染性
- 异步函数具有传染性 比如一个函数中使用了 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);```