You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何复用同步函数与异步协程的节流检查逻辑?

问题:如何复用同步与异步场景下的相似代码块

我编写了如下同步函数:

def check_for_throttling(r):
    if r.status_code == responses.THROTTLING:
        # <lots of other stuff>
        time.sleep(Throttle.DELAY)
        Throttle.DELAY = Throttle.DELAY + 2
    return r

同时也编写了如下异步协程:

async def check_for_throttling(r):
    if r.status_code == responses.THROTTLING:
        # <lots of other stuff>
        await asyncio.sleep(Throttle.DELAY)
        Throttle.DELAY = Throttle.DELAY + 2
    return r

二者逻辑几乎完全一致,仅sleep方式不同(一个用time.sleep(),另一个用asyncio.sleep())。我还有其他逻辑更复杂的类似场景,请问是否有办法复用同一代码块处理这两种场景?


解决方案

可以通过拆分核心逻辑与IO操作的方式来复用代码,以下是几种实用方案:

方案1:提取纯逻辑代码块(推荐)

把两个函数中除了sleep之外的核心业务逻辑单独抽成通用函数,同步和异步版本仅处理各自的sleep调用:

首先提取纯业务逻辑:

def _handle_throttling():
    # 这里放原代码里的<lots of other stuff>
    current_delay = Throttle.DELAY
    Throttle.DELAY += 2
    return current_delay

同步版本直接调用:

import time

def check_for_throttling(r):
    if r.status_code == responses.THROTTLING:
        delay = _handle_throttling()
        time.sleep(delay)
    return r

异步版本则用await调用异步sleep:

import asyncio

async def check_for_throttling(r):
    if r.status_code == responses.THROTTLING:
        delay = _handle_throttling()
        await asyncio.sleep(delay)
    return r

这种方式让90%的核心逻辑完全复用,只剩一行sleep的差异,简洁直观,无需额外依赖。

方案2:依赖注入sleep函数

如果想让逻辑结构更统一,可以把sleep操作作为参数传入通用逻辑函数,同步传time.sleep,异步则封装成可await的调用:

先编写通用协程逻辑:

async def _check_core(r, sleep_func):
    if r.status_code == responses.THROTTLING:
        # <lots of other stuff>
        await sleep_func(Throttle.DELAY)
        Throttle.DELAY += 2
    return r

同步版本用asyncio.run包装调用,同时把同步sleep适配成可await的函数:

import time
import asyncio

def check_for_throttling(r):
    async def sync_sleep_wrapper(delay):
        time.sleep(delay)
    return asyncio.run(_check_core(r, sync_sleep_wrapper))

异步版本直接使用:

import asyncio

async def check_for_throttling(r):
    return await _check_core(r, asyncio.sleep)

这种方式适合逻辑特别复杂、不想重复写判断分支的场景,但同步版本需要额外适配sleep函数,稍显繁琐。

方案3:使用统一IO库(可选)

如果项目允许引入第三方库,anyio提供了统一的同步/异步IO接口,它的anyio.sleep在两种环境下都能正常工作,只需写一份核心代码:

import anyio

async def check_for_throttling(r):
    if r.status_code == responses.THROTTLING:
        # <lots of other stuff>
        await anyio.sleep(Throttle.DELAY)
        Throttle.DELAY += 2
    return r

# 同步调用时用anyio.run包装
def sync_check_for_throttling(r):
    return anyio.run(check_for_throttling, r)

这种方式代码最简洁,但需要引入外部依赖,适合已经使用异步生态的项目。


内容的提问来源于stack exchange,提问作者ah2Bwise

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 03:43:39