(thenable: Thenable<T>)
| 84 | } |
| 85 | |
| 86 | function resolveThenable<T>(thenable: Thenable<T>): T { |
| 87 | switch (thenable.status) { |
| 88 | case 'fulfilled': { |
| 89 | const fulfilledValue: T = thenable.value; |
| 90 | return fulfilledValue; |
| 91 | } |
| 92 | case 'rejected': { |
| 93 | const rejectedError = thenable.reason; |
| 94 | throw rejectedError; |
| 95 | } |
| 96 | default: { |
| 97 | if (typeof thenable.status === 'string') { |
| 98 | // Only instrument the thenable if the status if not defined. If |
| 99 | // it's defined, but an unknown value, assume it's been instrumented by |
| 100 | // some custom userspace implementation. We treat it as "pending". |
| 101 | // Attach a dummy listener, to ensure that any lazy initialization can |
| 102 | // happen. Flight lazily parses JSON when the value is actually awaited. |
| 103 | thenable.then(noop, noop); |
| 104 | } else { |
| 105 | // This is an uncached thenable that we haven't seen before. |
| 106 | |
| 107 | // TODO: Detect infinite ping loops caused by uncached promises. |
| 108 | |
| 109 | const pendingThenable: PendingThenable<T> = (thenable: any); |
| 110 | pendingThenable.status = 'pending'; |
| 111 | pendingThenable.then( |
| 112 | fulfilledValue => { |
| 113 | if (thenable.status === 'pending') { |
| 114 | const fulfilledThenable: FulfilledThenable<T> = (thenable: any); |
| 115 | fulfilledThenable.status = 'fulfilled'; |
| 116 | fulfilledThenable.value = fulfilledValue; |
| 117 | } |
| 118 | }, |
| 119 | (error: mixed) => { |
| 120 | if (thenable.status === 'pending') { |
| 121 | const rejectedThenable: RejectedThenable<T> = (thenable: any); |
| 122 | rejectedThenable.status = 'rejected'; |
| 123 | rejectedThenable.reason = error; |
| 124 | } |
| 125 | }, |
| 126 | ); |
| 127 | } |
| 128 | |
| 129 | // Check one more time in case the thenable resolved synchronously. |
| 130 | switch ((thenable: Thenable<T>).status) { |
| 131 | case 'fulfilled': { |
| 132 | const fulfilledThenable: FulfilledThenable<T> = (thenable: any); |
| 133 | return fulfilledThenable.value; |
| 134 | } |
| 135 | case 'rejected': { |
| 136 | const rejectedThenable: RejectedThenable<T> = (thenable: any); |
| 137 | const rejectedError = rejectedThenable.reason; |
| 138 | throw rejectedError; |
| 139 | } |
| 140 | } |
| 141 | } |
| 142 | } |
| 143 | throw thenable; |
no test coverage detected