解决异步传染问题,将异步转同步,可以使用下面的方法:
修改前:
async function getUser() {
return await fetch('https://example').then(resp => resp.json())
}
async function m1() {
return await getUser()
}
async function m2() {
return await m1()
}
async function m3() {
return await m2()
}
async function main() {
const user = await m3()
console.log(user)
}
main()
修改后:
function getUser() {
return fetch('https://example')
}
function m1() {
return getUser()
}
function m2() {
return m1()
}
function m3() {
return m2()
}
function main() {
const user = m3()
console.log(user)
}
function run(func) {
let cache = []
let i = 0
const _originalFetch = window.fetch
// 先将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(resp => {
result.status = 'fulfilled'
result.data = resp
},err => {
result.status = 'rejected'
result.err = err
})
// 报错
throw prom
}
try {
// 执行函数,此时函数中的fetch方法已被重写
func()
} catch (err) {
if(err instanceof Promise) {
const reRun = () => {
i = 0
func()
}
err.then(reRun,reRun)
}
}
}
run(main)