【面试题】如何消除异步的传染性

文章讨论了在JavaScript中如何消除异步操作的传染性,即在使用async和await时避免整个调用链都变得异步。作者提出在源头处理,通过同步化异步动作并引入缓存机制,利用抛出异常的方式来实现。文中提供了一个名为eliAsync的函数示例,它重写了window.fetch方法,实现了请求的缓存和异常处理,从而在调用链中消除异步影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

我们在开发过程中都知道,如果要使用async 和 await 语法糖必须在函数使用的链路上全部都要使用async 和 await, 不够优雅,那么有什么办法可以消除异步的传染性呢?

常见使用方式

const getdata = async () => {
	const res = await fetch(url).then( response=>console.log(response))
}

const fn1 = async () => {
	await getdata()
}

const fn2 = async () => {
	await fn1()
}

const fn3 = async () => {
	await fn2()
}

fn3()

消除异步传染性

那么如何消除异步的传染性呢? 思路: 很明显必须在源头进行处理, 否则在链路的任意一环处理都不可能消除, 那么如何处理呢? 在请求的时候会有延迟,那么只有将异步的动作同步化,然后增加缓存才能解决异步的传染性, 也就是使用抛出异常的方式来解决该问题

	function getdata() {
	 	return fetch('./data.json');
	}
	  function m1() {
	      return getdata();
	  }
	  function m2() {
	      return m1();
	  }
	  function m3() {
	      return m2();
	  }
	  function main() {
	      const data = m3();
	      console.log(data);
	  }
	function eliAsync(func) {
		let cache = [];
		let i = 0;
		const _originalFetch = window.fetch;
		window.fetch = (...args) => {
			if(cache[i]) {
				if(cache[i].status === 'fulfilled') {
					return cache[i].data;
				} else if(cache[i].status === 'rejected') {
					throw cache[i].err;
				}
			}
			const result = {
				status: 'pending',
				data: null,
				err: null
			};
			cache[i++] = result;
			const prom = _originalFetch(...args).then(resp => resp.json()).then(res => {
				 result.status = 'fulfilled';
                 result.data = res;
			}, err => {
				reslut.status = 'rejected';
				result.err = err;
			});
			
			throw prom;
			
		}
			try {
				func();
			} catch(err) {
				if(err instanceof Promise) {
					const reRun = () => {
						i = 0;
						func();
					}
					err.then(reRun, reRun);
				}
			}
	};
eliAsync(fn3);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MaxLoongLvs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值