51
51
function await (PromiseInterface $ promise )
52
52
{
53
53
$ wait = true ;
54
- $ resolved = null ;
55
- $ exception = null ;
54
+ $ resolved = false ;
56
55
$ rejected = false ;
56
+ $ resolvedValue = null ;
57
+ $ rejectedThrowable = null ;
57
58
58
59
$ promise ->then (
59
- function ($ c ) use (&$ resolved , &$ wait ) {
60
- $ resolved = $ c ;
60
+ function ($ c ) use (&$ resolved , &$ resolvedValue , &$ wait ) {
61
+ $ resolvedValue = $ c ;
62
+ $ resolved = true ;
61
63
$ wait = false ;
62
64
Loop::stop ();
63
65
},
64
- function ($ error ) use (&$ exception , &$ rejected , &$ wait ) {
65
- $ exception = $ error ;
66
+ function ($ error ) use (&$ rejected , &$ rejectedThrowable , &$ wait ) {
67
+ // promise is rejected with an unexpected value (Promise API v1 or v2 only)
68
+ if (!$ error instanceof \Exception && !$ error instanceof \Throwable) {
69
+ $ error = new \UnexpectedValueException (
70
+ 'Promise rejected with unexpected value of type ' . (is_object ($ error ) ? get_class ($ error ) : gettype ($ error ))
71
+ );
72
+
73
+ // avoid garbage references by replacing all closures in call stack.
74
+ // what a lovely piece of code!
75
+ $ r = new \ReflectionProperty ('Exception ' , 'trace ' );
76
+ $ r ->setAccessible (true );
77
+ $ trace = $ r ->getValue ($ error );
78
+
79
+ // Exception trace arguments only available when zend.exception_ignore_args is not set
80
+ // @codeCoverageIgnoreStart
81
+ foreach ($ trace as $ ti => $ one ) {
82
+ if (isset ($ one ['args ' ])) {
83
+ foreach ($ one ['args ' ] as $ ai => $ arg ) {
84
+ if ($ arg instanceof \Closure) {
85
+ $ trace [$ ti ]['args ' ][$ ai ] = 'Object( ' . \get_class ($ arg ) . ') ' ;
86
+ }
87
+ }
88
+ }
89
+ }
90
+ // @codeCoverageIgnoreEnd
91
+ $ r ->setValue ($ error , $ trace );
92
+ }
93
+
94
+ $ rejectedThrowable = $ error ;
66
95
$ rejected = true ;
67
96
$ wait = false ;
68
97
Loop::stop ();
@@ -73,22 +102,23 @@ function ($error) use (&$exception, &$rejected, &$wait) {
73
102
// argument does not show up in the stack trace in PHP 7+ only.
74
103
$ promise = null ;
75
104
105
+ if ($ rejected ) {
106
+ throw $ rejectedThrowable ;
107
+ }
108
+
109
+ if ($ resolved ) {
110
+ return $ resolvedValue ;
111
+ }
112
+
76
113
while ($ wait ) {
77
114
Loop::run ();
78
115
}
79
116
80
117
if ($ rejected ) {
81
- // promise is rejected with an unexpected value (Promise API v1 or v2 only)
82
- if (!$ exception instanceof \Exception && !$ exception instanceof \Throwable) {
83
- $ exception = new \UnexpectedValueException (
84
- 'Promise rejected with unexpected value of type ' . (is_object ($ exception ) ? get_class ($ exception ) : gettype ($ exception ))
85
- );
86
- }
87
-
88
- throw $ exception ;
118
+ throw $ rejectedThrowable ;
89
119
}
90
120
91
- return $ resolved ;
121
+ return $ resolvedValue ;
92
122
}
93
123
94
124
/**
0 commit comments