1 | import { AsyncIterableX } from './asynciterablex';
|
2 | import { sleep } from './_sleep';
|
3 | export class TimeoutError extends Error {
|
4 | constructor() {
|
5 | super();
|
6 | Object.setPrototypeOf(this, TimeoutError.prototype);
|
7 | this.message = 'Timeout has occurred';
|
8 | }
|
9 | }
|
10 | const VALUE_TYPE = 'value';
|
11 | const ERROR_TYPE = 'error';
|
12 | export class TimeoutAsyncIterable extends AsyncIterableX {
|
13 | constructor(source, dueTime) {
|
14 | super();
|
15 | this._source = source;
|
16 | this._dueTime = dueTime;
|
17 | }
|
18 | async *[Symbol.asyncIterator]() {
|
19 | const it = this._source[Symbol.asyncIterator]();
|
20 | while (1) {
|
21 | const { type, value } = await Promise.race([
|
22 | it.next().then(value => {
|
23 | return { type: VALUE_TYPE, value };
|
24 | }),
|
25 | sleep(this._dueTime).then(() => {
|
26 | return { type: ERROR_TYPE };
|
27 | })
|
28 | ]);
|
29 | if (type === ERROR_TYPE) {
|
30 | throw new TimeoutError();
|
31 | }
|
32 | if (!value || value.done) {
|
33 | break;
|
34 | }
|
35 | yield value.value;
|
36 | }
|
37 | }
|
38 | }
|
39 | export function timeout(source, dueTime) {
|
40 | return new TimeoutAsyncIterable(source, dueTime);
|
41 | }
|
42 |
|
43 |
|