zoukankan      html  css  js  c++  java
  • 利用yield将异步回调同步化

    《python cookbook》上这段代码利用yield将异步回调同步化,这跟tornado的@gen.coroutine用法好像,感觉tornado的gen.coroutine装饰器背后可能就是这个原理,将被装饰函数的yield逐步遍历并等待被装饰函数下次yield出,若收到生成器结束的异常,则装饰器函数也退出。同步化的编程方式还有一个特点就是整个流程全程都是可见的,不会有上下文环境访问不到

    
    from queue import Queue
    from functools import wraps
    
    
    def apply_async(func, args, *, callback):
        # Compute the result
        result = func(*args)
    
        # Invoke the callback with the result
        callback(result)
    
    class Async:
        def __init__(self, func, args):
            self.func = func
            self.args = args
    
    def inlined_async(func):
        @wraps(func)
        def wrapper(*args):
            f = func(*args)
            result_queue = Queue()
            result_queue.put(None)
            while True:
                result = result_queue.get()
                try:
                    ## 注意,这里不仅发送消息给生成器,并且等待生成器返回值
                    a = f.send(result)
                    apply_async(a.func, a.args, callback=result_queue.put)
                except StopIteration:
                    break
        return wrapper
    
    
    
    
    def add(x, y):
        return x + y
    
    @inlined_async
    def test():
        r = yield Async(add, (2, 3))
        print(r)
        r = yield Async(add, ('hello', 'world'))
        print(r)
        for n in range(10):
            r = yield Async(add, (n, n))
            print(r)
        print('Goodbye')
    
    
    def main():
        test()
    
    
    main()
    
    
  • 相关阅读:
    MvvmTest
    win8 app 相关的几个网站
    autp
    分析WPF代码工具
    mdsn
    线程和委托
    C#guanli
    学习Boost小结(一)
    Boost.test库的配置
    自己真是太没正事了.
  • 原文地址:https://www.cnblogs.com/encode/p/6397862.html
Copyright © 2011-2022 走看看