Completed
Push — master ( 7247a2...0efe74 )
by Stéphane
06:34
created

Promise::setLoop()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4286
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace Http\Adapter\React;
4
5
use React\EventLoop\LoopInterface;
6
use React\Promise\PromiseInterface as ReactPromise;
7
use Http\Client\Exception;
8
use Http\Promise\Promise as HttpPromise;
9
use Psr\Http\Message\ResponseInterface;
10
11
/**
12
 * React promise adapter implementation.
13
 *
14
 * @author Stéphane Hulard <[email protected]>
15
 */
16
class Promise implements HttpPromise
17
{
18
    /**
19
     * Promise status.
20
     *
21
     * @var string
22
     */
23
    private $state = HttpPromise::PENDING;
24
25
    /**
26
     * Adapted React promise.
27
     *
28
     * @var ReactPromise
29
     */
30
    private $promise;
31
32
    /**
33
     * PSR7 received response.
34
     *
35
     * @var ResponseInterface
36
     */
37
    private $response;
38
39
    /**
40
     * Execution error.
41
     *
42
     * @var Exception
43
     */
44
    private $exception;
45
46
    /**
47
     * React Event Loop used for synchronous processing.
48
     *
49
     * @var LoopInterface
50
     */
51
    private $loop;
52
53
    /**
54
     * Initialize the promise.
55
     *
56
     * @param ReactPromise $promise
57
     */
58
    public function __construct(ReactPromise $promise)
59
    {
60
        $promise->then(
61
            function (ResponseInterface $response) {
62
                $this->state = HttpPromise::FULFILLED;
63
                $this->response = $response;
64
            },
65
            function (Exception $error) {
66
                $this->state = HttpPromise::REJECTED;
67
                $this->exception = $error;
68
            }
69
        );
70
        $this->promise = $promise;
71
    }
72
73
    /**
74
     * Allow to apply callable when the promise resolve.
75
     *
76
     * @param callable|null $onFulfilled
77
     * @param callable|null $onRejected
78
     *
79
     * @return ReactPromiseAdapter
80
     */
81
    public function then(callable $onFulfilled = null, callable $onRejected = null)
82
    {
83
        $this->promise->then(function () use ($onFulfilled) {
84
            if (null !== $onFulfilled) {
85
                call_user_func($onFulfilled, $this->response);
86
            }
87
        }, function () use ($onRejected) {
88
            if (null !== $onRejected) {
89
                call_user_func($onRejected, $this->exception);
90
            }
91
        });
92
93
        return $this;
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99
    public function getState()
100
    {
101
        return $this->state;
102
    }
103
104
    /**
105
     * Set EventLoop used for synchronous processing.
106
     *
107
     * @param LoopInterface $loop
108
     *
109
     * @return ReactPromiseAdapter
110
     */
111
    public function setLoop(LoopInterface $loop)
112
    {
113
        $this->loop = $loop;
114
115
        return $this;
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function wait($unwrap = true)
122
    {
123
        if (null === $this->loop) {
124
            throw new \LogicException('You must set the loop before wait!');
125
        }
126
        while (HttpPromise::PENDING === $this->getState()) {
127
            $this->loop->tick();
128
        }
129
130
        if ($unwrap) {
131
            if (HttpPromise::REJECTED == $this->getState()) {
132
                throw $this->exception;
133
            }
134
135
            return $this->response;
136
        }
137
    }
138
}
139