Skip to content

Commit 945f774

Browse files
committed
Adapt React\Promise\PromiseInterface to Http\Client\Promise
1 parent 4cdc785 commit 945f774

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed

src/ReactPromiseAdapter.php

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

0 commit comments

Comments
 (0)