Python-asyncio

1.基于生成式构造带状态的函数

一个函数多次调用都从上次返回的地方重新开始,相当于给一个机会从函数执行的中间切出去,再切回来的时候从原来的地方重新开始,这样能避免那种需要在函数执行过程中保留过多上下文信息的问题。对于异步io,如果我们能保留函数上下文,在等待异步io返回的时候切出去,这样就不需要费力写回调链了,一切就像同步调用一样,await一下,返回之后继续。唯一的问题在于,异步io本身是有传染性的,为了最大程度利用io等待的时间,我们实际希望协程在异步io切出去之后,程序能继续调度其它task

2.sleep函数实现

@types.coroutine
def __sleep0():
    """Skip one event loop run cycle.

    This is a private helper for 'asyncio.sleep()', used
    when the 'delay' is set to 0.  It uses a bare 'yield'
    expression (which Task.__step knows how to handle)
    instead of creating a Future object.
    """
    yield


async def sleep(delay, result=None, *, loop=None):
    """Coroutine that completes after a given time (in seconds)."""
    if delay <= 0:
        await __sleep0()
        return result

    if loop is None:
        loop = events.get_event_loop()
    future = loop.create_future()
    h = loop.call_later(delay,
                        futures._set_result_unless_cancelled,
                        future, result)
    try:
        return await future
    finally:
        h.cancel()

这个地方是个很好的例子,用Future类封装事件等待,避免关心套接字相关的细节,但也意味着,我们如果希望将原有的io操作变成异步型的话,要么封装自己的协程,像sleep这样,将程序变成loop.run_until_complete,要么就是程序库自己提供了兼容asyncio的接口。

你可能感兴趣的:(Python-asyncio)