首页JS消除异步函数的传染性

消除异步函数的传染性

分类JS时间2025-02-17 16:47:43发布RustStream浏览114
摘要:因为fetch是一个IO操作,所以是异步的。因为fetch是异步的,所以导致后面所有函数调用都需要处理 async await 代码如下 async function getData( { const data = await fetch('http://localhost:9000?id=1' return data } async function m1( { const data = await getData( return data } async function main( { const data = await m1( ; console.log(data } main( 实现不需要写async await 照样可以使代码运行 function getData( { const data = fetch('http://localhost:9000?id=1' return data } function m1( { const data = getData( return data } function main( { const data = m1( ; console.log(data } 思路如下: 异步传染性来源于fetch,所以改造一下自带的fecth...

因为fetch是一个IO操作,所以是异步的。因为fetch是异步的,所以导致后面所有函数调用都需要处理 async await

代码如下

async function getData() {
    const data = await fetch('http://localhost:9000?id=1')
    return data
}


async function m1(){
    const data = await getData()
    return data
}

async function main() {
    const data = await m1();
    console.log(data)
}

main()

实现不需要写async await 照样可以使代码运行

function getData() {
    const data = fetch('http://localhost:9000?id=1')
    return data
}


function m1(){
    const data = getData()
    return data
}

function main() {
    const data = m1();
    console.log(data)
}

思路如下:

异步传染性来源于fetch,所以改造一下自带的fecth

利用try…catch并通过缓存的方式来处理异步请求结果,从而在后续的调用中直接使用缓存的数据。

  1. 定义一个新的fetch函数。在新的fetch方法中,首先判断cache的状态,如果已经有缓存的数据,则直接返回缓存的值。
  2. 如果没有缓存,则调用原fetch方法发起请求。
  3. 可以在请求等待返回数据时,立刻抛出一个特定的错误,不等待。
  4. fetch返回数据后缓存起来,通过try…catch来捕获抛出的特定错误,重新去启动main函数的调用。
  5. 重新启动main函数的调用,调用新定义的fetch函数,拿缓存里面的数据

代码实现

// 定义一个辅助函数,避免改变全部的fetch方法
// 传入一个回调函数
function _run(func){
    // 1. 先保存原先fetch方法
    const oldFetch = window.fetch;
    // 2. 修改fetch
    const cache = {
        // 状态参数:pending  fulfilled  rejected
        status: 'pending', 
        value: null
    }
    function newFetch(arg){
        if(cache.status === 'fulfilled'){
            return cache.value
        }else if (cache.status === 'rejected'){
            throw cache.value
        }
        const p = oldFetch(arg).then((res) => res.json()).then((res) => {
            cache.status = 'fulfilled'
            cache.value = res
        }, (err) => {
            cache.status = 'rejected'
            cache.value = err
        })
        // 抛出一个特定的错误
        throw p;
    }
    window.fetch = newFetch;
    // 3. 运行回调函数
    try {
        func();
    }catch(err){
        // 如果返回的是自己定义的Promise错误,则重新请求一次,从定义的缓存里面读取异步返回的数据
        if( err instanceof Promise ){
            err.finally(() => {
                window.fetch = newFetch
                func()
                window.fetch = oldFetch
            })
        }
    }
    
    // 4. 复原fetch方法
    window.fetch = oldFetch;
}

本文链接:https://blog.smallhao.fun/?id=11 转载需授权!

分享到:

Chen’Blog版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

JavaScript
JS实现简单的拖拽效果 并发任务控制

游客 回复需填写必要信息
召唤伊斯特瓦尔