What does async/await do?

前端 未结 2 1928
轮回少年
轮回少年 2021-02-15 18:16

I\'m trying to wrap my head around async/await in python.

Am I on the right track?

  • async and @coroutine functions returns corouti
2条回答
  •  不思量自难忘°
    2021-02-15 18:54

    Demo code:

    (illustrates whole control flow between async and types.coroutine and event loop)

    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()
    

    Result:

    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
    

提交回复
热议问题