async / await做了什么?

时间:2017-09-22 11:42:07

标签: python python-3.x async-await

我正试图在python中绕过async / await。

我是在正确的轨道上吗?

  • async@coroutine函数返回coroutine / generator,而不是返回值。
  • await提取coroutine / generator的实际返回值

  • async函数结果(coroutines)意味着添加到事件循环中。

  • await在事件循环和等待的协程之间创建“桥梁”(启用下一个点)。
  • @coroutine的{​​{1}}直接与事件循环进行通信。 (跳过等待结果的直接来电者)

  • yield只能在异步函数中使用。

  • await只能在yield内使用。

@coroutine = @coroutine

2 个答案:

答案 0 :(得分:9)

  

async@coroutine函数返回coroutine / generator,而不是返回值

技术上,types.coroutine返回一个基于生成器的协程,它与生成器不同,而且与协程不同。

  

await提取coroutine / generator的实际返回值。

await,与yield from类似,暂停协程的执行,直到等待它完成并返回结果为止。

  

异步函数结果(协程)意味着要添加到事件循环中。

是。

  

await在事件循环和等待的协程之间创建“桥梁”(启用下一个点)。

await创建一个挂起点,指示事件循环将发生一些I / O操作,从而允许它切换到另一个任务。

  

@ coroutine的yield直接与事件循环通信。 (跳过等待结果的直接来电者)

不,基于生成器的协同程序使用yield from的方式与await类似,而不是yield

  

await只能在异步函数中使用。

  

产量只能在协程内使用。

yield from可以在基于生成器的协同程序(使用types.coroutine装饰的生成器)中使用,并且自Python 3.6起,在async函数中使用,从而产生异步生成器。

答案 1 :(得分:-1)

演示代码:

(说明asynctypes.coroutine和事件循环之间的整个控制流程

import types


class EL:
    """Fake An event loop."""

    def __init__(self, outer_async):
        self.outer_async = outer_async

    def loop(self):
        print('    EL.loop : outer_async.send(None)')
        send_result = self.outer_async.send(None) # seed outer_async.
        print('    EL.loop : outer_async.send(None) -> outer_async_send_result = {}'.format(send_result))

        do_loop = True
        loop_counter = 0

        while do_loop:
            print()
            loop_counter += 1
            try:
                arg = send_result + '-loop(send-{})'.format(loop_counter)
                print('    EL.loop.while : task.outer_async.send({})'.format(arg))
                send_result = self.outer_async.send(arg) # raises StopIteration.
                print('    EL.loop.while : task.outer_async.send({}) -> send_result = {}'.format(arg, send_result))
            except StopIteration as e:
                print('    EL.loop.while : except StopIteration -> {}'.format(e.value))
                do_loop = False
        return loop_counter


async def outer_async(label):
    inner_coro_arg = label + '-A1'
    print('        outer_async({}) : await inner_coro({})'.format(label, inner_coro_arg))
    await_result = await inner_coro(inner_coro_arg)
    print('        outer_async({}) : await inner_coro({}) -> await_result = {}'.format(label, inner_coro_arg, await_result))

    inner_coro_arg = label + '-A2'
    print('        outer_async({}) : await inner_coro({})'.format(label, inner_coro_arg))
    await_result = await inner_coro(inner_coro_arg)
    print('        outer_async({}) : await inner_coro({}) -> await_result = {}'.format(label, inner_coro_arg, await_result))
    return 555555


@types.coroutine
def inner_coro(inner_coro_label):
    yld_arg = inner_coro_label + '-C(yield)'
    print('            inner_coro({}) : yield({})'.format(inner_coro_label, yld_arg))
    yield_result = yield yld_arg
    print('            inner_coro({}) : yield({}) -> yield_result = {}'.format(inner_coro_label, yld_arg, yield_result))
    return_value = yield_result + '-C(return)'
    print('            inner_coro({}) : return -> {}'.format(inner_coro_label, return_value))
    return return_value


def main():
    loop = EL(outer_async('$$'))
    print('main() : loop.loop')
    loop_outer_async = loop.loop()
    print('main() : loop.loop -> {}'.format(loop_outer_async))


if __name__ == '__main__':
    main()

结果:

main() : loop.loop
    EL.loop : outer_async.send(None)
        outer_async($$) : await inner_coro($$-A1)
            inner_coro($$-A1) : yield($$-A1-C(yield))
    EL.loop : outer_async.send(None) -> outer_async_send_result = $$-A1-C(yield)

    EL.loop.while : task.outer_async.send($$-A1-C(yield)-loop(send-1))
            inner_coro($$-A1) : yield($$-A1-C(yield)) -> yield_result = $$-A1-C(yield)-loop(send-1)
            inner_coro($$-A1) : return -> $$-A1-C(yield)-loop(send-1)-C(return)
        outer_async($$) : await inner_coro($$-A1) -> await_result = $$-A1-C(yield)-loop(send-1)-C(return)
        outer_async($$) : await inner_coro($$-A2)
            inner_coro($$-A2) : yield($$-A2-C(yield))
    EL.loop.while : task.outer_async.send($$-A1-C(yield)-loop(send-1)) -> send_result = $$-A2-C(yield)

    EL.loop.while : task.outer_async.send($$-A2-C(yield)-loop(send-2))
            inner_coro($$-A2) : yield($$-A2-C(yield)) -> yield_result = $$-A2-C(yield)-loop(send-2)
            inner_coro($$-A2) : return -> $$-A2-C(yield)-loop(send-2)-C(return)
        outer_async($$) : await inner_coro($$-A2) -> await_result = $$-A2-C(yield)-loop(send-2)-C(return)
    EL.loop.while : except StopIteration -> 555555
main() : loop.loop -> 2