协程同步代码完成异步结构

 

这种情况解决的是:一个程序有多个回调,但是回调执行顺序是已知的、确定的,那么所有回调函数可以写在个函数里面即可,
按照同步代码结构完成异步的逻辑,虽然还是有回调,但是回调不再需要关心业务,因为携程负责回调业务的call_back,而业务call-back可以直接写在异步调用的附件,用同步代码结构处理业务回调,由于是同步代码,在一个函数内,状态直接可以共享。
如果不是同步代码,那么各个函数传递信息要不通过返回值,要不在如self里面设置属性
协程的作用可以在指定地方暂停,并且可以恢复现场,甚至还可以通过send传参

下面代码中:
1 用线程模拟注册的回调函数以后,被外面的信号主动触发
2 为了保证yield future_result 在call_back 前面执行,sleep(0.1)了一次

import threading,random,time

class FutureResult(object):
    def __init__(self):
        self.call_back_list = []
        self.result = None

    def add_call_back(self,call_back):
        print "add_call_back"
        self.call_back_list.append(call_back)

    def set_result(self,result):
        self.result = result
        for call_back in self.call_back_list:
            call_back(self)

class TaskExecutor(object):
    def __init__(self,task_func):
        self.task_func = task_func


    def start_execute(self):
        future_result = FutureResult()
        future_result.set_result(None)
        self.step(future_result)

    def step(self,future_result):
        try:
            next_future_result = self.task_func.send(future_result.result)
        except StopIteration:
            print "StopIteration"
            return
        next_future_result.add_call_back(self.step)

class Task(object):
    def __init__(self,task_id):
        self.task_id = task_id
        self.current_value = 0

    def task_func(self):
        future_result = FutureResult()
        def call_back1():
            time.sleep(0.1)
            print "call_back 1"
            future_result.set_result(0)

        call_back_thread = threading.Thread(target=call_back1, args=())
        call_back_thread.start()

        yield future_result


        total_num = 0
        while total_num < 8:
            future_result = FutureResult()
            def call_back():
                time.sleep(0.1)
                num = random.randint(0,3)
                print "call_back num",num
                future_result.set_result(num)
                return

            call_back_thread = threading.Thread(target=call_back, args=())
            call_back_thread.start()
            last_num = yield future_result
            print "last_num", last_num
            total_num += last_num

if __name__ == "__main__":
    task1 = Task(1)
    task_executor = TaskExecutor(task1.task_func())
    task_executor.start_execute()

 

posted @ 2017-10-21 19:45  notlate  阅读(284)  评论(0)    收藏  举报