[编程思想进行曲]guzzlehttp组件之promises项目的设计思想整理

1.前言

最近找的项目都是packagist上的热门项目,其中guzzlehttp组件应该算是比较知名的,今天我来学习下它的依赖子组件promises的故事。

2.promise的介绍

promise的概念,最早是前端优化异步回调函数嵌套问题所推出的新的语法糖,立志于优雅的使用链式结构解决回调地狱,之前有一篇相关介绍文章,点击这里。promises项目的发起原因也是想使用PHP的方式解决这个问题。

3.设计思想

该项目的原理主要还是使用队列的方式,将成功和失败的处理回调函数压入堆栈。当用户传参处理成功或者失败的方法时,会遍历处理堆栈绑定到相关的处理函数中。最后,通过弹出执行队列的处理函数,再进行回调函数的处理。

3.1 主要功能的类布局

3.2 设计特色

promise这个项目虽然代码量不大,但是也能看出作者对业务拆分的非常细致,其中把面向过程的编码风格和面向对象的风格相结合使用,扩大两种风格的优势,值得借鉴。在上面的UML类图中,我们看到每个Promise实现都依赖于TaskQueue类,而作者却是使用了面向过程的方式封装了TaskQueue的使用,我们看下面一段代码:

这种方式,在使用TaskQueue前可以灵活的调整相关业务逻辑,然后通过全局函数注入到相关业务中。下面来看下,它的使用方式:

4.简易版的promise

下面,我来写一个简化版的promise来概括下这个promise的主要原理。

class Promise
{
    private $handler = [];
    private $queue = [];

    public function __construct() {

    }

    public function then($success, $failure) {
        $p = new Promise();
        $this->handler [] = [$p, $success, $failure];
        return $p;
    }

    public function resolve($value) {
        $handlers = $this->handler;
        $this->queue[] = (static function() use ($handlers, $value) {
            foreach($handlers as $h) {
                $promise = $h[0];
                $promise->resolve($h[1]($value));
            }
        });
    }

    public function reject($value) {
        $handlers = $this->handler;
        $this->queue[] = (static function() use ($handlers, $value) {
            foreach($handlers as $h) {
                $promise = $h[0];
                $promise->reject($h[2]($value));
            }
        });
    }

    public function __destruct() {
        while($task = array_shift($this->queue)) {
            $task();
        }
    }
}

$a = new Promise();
$a->then(function($c) use (&$a){
    echo 'success with ' . $c . PHP_EOL;
    return 1;
}, function($d){
    echo 'failure with ' . $d .  PHP_EOL;
    return 2;
})->then(function($e){
    echo 'second success with ' . $e . PHP_EOL;
}, function($f){
    echo 'second failure with ' . $f . PHP_EOL;
});

$a->resolve('a');

5.项目地址

github地址

https://github.com/guzzle/promises
如无特殊说明,文章均为本站原创,转载请注明出处。如发现有什么不对的地方,希望得到您的指点。

发表评论

电子邮件地址不会被公开。 必填项已用*标注