如何消除函数异步性?

106 阅读1分钟

消除异步传染性

async function getUser(){
    return await fetch('./1.json);
}

async function m1(){
    const user = await getUser();
    // other works
    return user;
}

async function m2(){
    const user = await m1();
    // other works
    return user;
}

async function m3(){
    const user = await m2();
    // other works
    return user;
}

async function main(){
    const user = await m3();
    // other works
    console.log(user)
}

如何消除函数异步性?(react 副作用问题)函数式运行环境

function run(func){
    // 1.改动fetch
    const oldFetch = window.fetch;
    // 生产环境需要适配多次调用fetch的情况,调用几次可以用数组表示
    const cache = {
        status:"pending",
        value:null
    };
    function newFetch(...args){
        if(cache.status === "fulfilled"){
            return cache.value;
        }else if(cache.status === "rejected"){
            throw cache.value;
        }
        // 没有缓存
        // 发送请求
        const p = oldFetch(...args).then((data)=>{
            cache.value = data;
            cache.status = "fulfilled";
        }).catch((err)=>{
            cache.value = err;
            cache.status = "rejected";
        })
        // 抛出错误
        throw p;
        }

    }
    window.fetch = newFetch;
    // 2.执行func
    try{
       func();
    }
    catch(err){}{
        // 等待请求完成后重新运行func
        // 此处不严谨,应该考虑error是否满足Promise A+ 规范,而非下面只判断是ES6 Prmoise A+ 规范(Promise具有互操作性,不一定是ES6的)
        if(err instanceof Promise){
            err.finally(()=>{
                window.fetch = newFetch;
                func();
                window.fetch = oldFetch;
            });
        }
    }
    // 3.改回fetch
    window.fetch = oldFetch;
}

React Suspence 组件参照上述思路实现 React 里无异步组件,Vue3里的setup函数如果返回的是Promise的话,vue会将它作为异步组件处理。