消除异步函数的传染性简单实现

文章介绍了一种方法来消除异步函数的传染性,通过eliminateAsync函数,可以在不增加async和await的情况下,获取异步代码的结果。该函数利用缓存机制,在异步操作完成后存储结果,以便后续调用直接获取,减少了代码量和维护复杂性。
摘要由CSDN通过智能技术生成

我们js是单线程,如果想要获取异步代码并且执行顺序还得是同步的话,我们可以用async 和await实现,这个应该都不陌生对吧

但是像例如下面这种例子,我main函数里返回一个promise,可以实现获取异步信息,所以后面函数要想调用必须得加上async awiat去等待数据获取再返回,这样如果是函数式编程的话就会形成大问题,只要有一个函数返回的是promise,后面函数如果想要返回正确的数据就得增加async和await去实现,无形中增加了代码量和维护

function main(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve('收到数据并返回信息')
        },1000)
    })
}

async function f1(){
    return await main()
}

async function f2(){
    let info = await f1()
    console.log(info);
}
f2() // 过一秒后打印 ‘收到数据并返回信息’

所以有没有什么方法可以消除异步函数的传染性呢?😱其实是可以的,这是我再一些大牛那看到类似下面这段代码就能实现

// 定义一个执行函数
function eliminateAsync(func){
    let i = 0
    let cache = [] // 用于缓存数据
    let _originMain = main // 把异步函数赋值到一个变量供后面执行
    window.main = (...arg)=>{  // 重新定义异步函数
        // 判断缓存中有没有数据,第一次肯定没有
        if(cache[i]){
            // 如果有缓存数据
            // 如果状态是fulfilled的,就返回缓存数据
            if(cache[i].status === 'fulfilled'){
                return cache[i].data
            }else{
            // 如果异步函数执行错误了就返回错误信息
                throw cache[i].error
            }
        }
        let result = {
            status: 'pending',
            data: null,
            error: null
        }
        // 保存缓存信息,第一次缓存数据是假缓存
        cache[i++] = result
        // 执行一函数,第一次不等待函数执行完,执行下面的抛出错误 throw pro
        let pro = _originMain(...arg).then(
            (resp)=> {
                // 把数据缓存起来
                result.status = 'fulfilled'
                result.data = resp
            },
            (err)=> {
                // 把错误数据缓存起来
                result.status ='rejected'
                result.error = err
            }
        )
       throw pro
    }
    try{
        func()
    }catch(err){
        
        if(err instanceof Promise){
            const reRun = ()=>{
                i = 0
                func()
            }
            // 接收到抛出的错误后,再等待异步函数执行完成后重新运行传进来的函数,下次运行
            // 就能拿到缓存的数据了,因为异步函数已经执行完毕,缓存已经保存了
            err.then(reRun,reRun)
        }
    }
}
function main(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve('收到反馈和案说法')
        },1000)
    })
}
function f1(){
    return main()
}
function f2(){
    // 这里就不需要增加async和await了
    console.log(11) // 其实你会发现这个打印执行了2次,明白其中道理就会知道为什么会打印2次
    let user = f1()
    console.log(user);
}


eliminateAsync(f2) // 一秒过后打印 ‘收到数据并返回信息’

这里面的逻辑呢其实就是在运行异步函数时,不等待它返回,而是直接执行后面代码,等异步函数执行完后再把数据缓存起来,再一次调用传进去的函数获取到缓存信息并返回

我第一次看也是一脸懵,可以反复多看几次就能明白

在C#中,可以通过使用异步和等待(async/await)来消除异步的传染。异步传染性是指当一个方法是异步的时,调用该方法的方法也必须是异步的,并且这个过程会一直传递下去。为了消除异步传染性,可以使用以下四种方法: 1. 异步委托:定义一个与需要调用的方法具有相同签名的委托,并使用异步关键字修饰该委托,然后通过调用委托的BeginInvoke和EndInvoke方法来实现异步调用。 2. Task类:使用Task类来执行异步操作。可以使用Task.Run方法来启动一个新的任务,并使用await关键字等待任务的完成。 3. async/await:使用async/await关键字来标记方法为异步,并使用await关键字等待异步操作的完成。在异步方法中,可以使用await关键字等待另一个异步方法的完成,而无需标记该方法为异步。 4. 异步迭代器:使用yield关键字和IAsyncEnumerable/IAsyncEnumerator接口来创建异步迭代器方法。在异步迭代器方法中,可以使用await关键字和yield return语句来返回异步生成的元素。 通过使用以上四种方法,可以在C#中有效地消除异步传染性,使得只有需要异步处理的方法才是异步的,而其他方法可以继续以同步方式调用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C#异步调用四大方法](https://download.csdn.net/download/weixin_38707862/13757502)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [c#入门-异步方法](https://blog.csdn.net/zms9110750/article/details/128810315)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值