(转)消除异步的传染性【渡一教育】

303 阅读1分钟
function getUser() {
	return fetch('https://my-json-server.typicode.com/typicode/demo/profile');
}

function m1() {
	// other works
	return getUser();
}

function m2() {
	// other works
	return m1();
}

function m3() {
	// other works
	return m2();
}

function main() {
	console.log(11111)
	const intervalId = setInterval(() => {
		console.log('...')
	}, 1000);
	const user = m3()
	console.log('user :>> ', user);

}

async function run(func) {
	let _orignFetch = window.fetch
	let cache = [];
	let i = 0

	window.fetch = (...arg) => {
		if (cache[i]) {
			if (cache[i].status == 'fulfilled') {
				return cache[i].data
			} else if (cache[i].status == 'rejected') {
				throw cache[i].err
			}
		}
		const reslut = {
			status: 'pending',
			data: null,
			err: null
		}
		cache[i++] = reslut
		// 发送真正的请求
		const prom = _orignFetch(...arg)
			.then((resp) => {
				console.log('prom _orignFetch -------->')
				let js = resp.json()
				return js
			})
			.then((resp) => {
					reslut.status = 'fulfilled'
					reslut.data = resp;
				},
				(err) => {
					reslut.status = 'rejected'
					reslut.err = 'err'
				})
		// 报错
		throw prom;
	};

	try {
		func()
	} catch (err) {
		// 假设 err 是一个 Promise 实例  
		if (err instanceof Promise) {
			console.log('catch')

			const reRun = () => {
				// 重置 i 的值(假设 i 是之前定义的某个变量)  
				i = 0;
				// 调用 func 函数  
				func();
			};

			await doSomething();

			console.log('prom 另一个then-------->')
			// 正确使用 then 方法  
			err.then(reRun, reRun); // 或者使用 err.then(reRun).catch(reRun);  
			
			await doSomething();
			console.log('end -------->')

		}
	}
}

run(main)

function delay(ms) {
	return new Promise(resolve => setTimeout(resolve, ms));
}

async function doSomething() {
	console.log("超长操作");

	let s = 15000

	// 等待2秒  
	await delay(s);

	// 现在这个操作会在2秒后执行  
	console.log("超长操作后" + (s / 1000) + "秒执行");
}

打印结果:

image.png


另一问题:

image.png