Python原生的promise/future网上的用法特别少,看起来还挺难用的,于是就自己设计了一个。

(有一个第三方库叫promise然而那个设计完全看不懂可能那都是大佬们才配用的吧)

设计思路都写在代码里面了(简单来说就是开线程),开销可能会挺大。(原生Python用的是协程 我不会用

import threading


class Future(object):
    # 继承于threading.Thread的类
    class FutureThread(threading.Thread):
        # 初始化线程
        def __init__(self, func, argv=()):
            threading.Thread.__init__(self)
            self.func = func
            self.argv = argv

        # 运行函数 并将返回值存起来
        def run(self):
            self.result = self.func(*self.argv)


    # 初始化Future
    # 放入函数和参数就能直接开启一个线程运行
    # 异步操作
    def __init__(self, func, argv=()):
        self.func = func
        self.argv = argv
        self.thread = Future.FutureThread(self.func, self.argv)
        self.thread.start()


    # 执行完传入函数后执行另外一个函数
    # 当前Future的结果会放在函数的最后一个参数中(如果不希望这样设计可以自行修改)
    # 异步操作
    def Then(self, func, argv=()):
        def Func(obj, func, argv):
            obj.thread.join()
            # 结果会放入最后一个参数中
            return func(*argv, obj.thread.result)

        # 返回一个Future即一个新的线程去等待前面的线程完成再进行这个操作
        return Future(Func, (self, func, argv))


    # all_list中传的是全是Future的tuple或list
    # 返回一个值是一个Future
    # 返回的Future使用Then即当所有传入的Future都执行完毕后会将结果传入Then中的函数运行
    @staticmethod
    def All(all_list=()):
        def Func(all=()):            
            for arg in all_list:
                arg.thread.join()
            return [arg.thread.result for arg in all_list]

        return Future(Func, (all_list, ))


    # 等待线程执行完毕后 获取返回值
    # 同步操作
    def Get(self):
        self.thread.join()
        return self.thread.result


# 单元测试
if __name__ == "__main__":
    import time
    def f(*args):
        time.sleep(1.0)
        return list(args)
    start = time.time()
    print(
        Future.All(
            (
                Future.All(
                    (
                        Future(f, (1, )),
                        Future(f, (2, 3)),
                    )
                ).Then(f, (4, 5)),
                Future(f, (6, )),
            )
        ).Then(f, (7, 8)).Then(f, (9, )).Get()
    )
    end = time.time()
    print(end - start, 's')

以上的单元测试会输出:

[9, [7, 8, [[4, 5, [[1], [2, 3]]], [6]]]]
4.00438666343689 s

因为All函数传入的顺序会按照这个顺序传下去所以每一次的结果都是一样的而不会因为多线程而受到影响。

同时可以看出总共运行了6次函数f,但总时间只有4s。