async.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  6. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  7. return new (P || (P = Promise))(function (resolve, reject) {
  8. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  9. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  10. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  11. step((generator = generator.apply(thisArg, _arguments || [])).next());
  12. });
  13. };
  14. var __asyncValues = (this && this.__asyncValues) || function (o) {
  15. if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
  16. var m = o[Symbol.asyncIterator], i;
  17. return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
  18. function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
  19. function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
  20. };
  21. import { CancellationTokenSource } from './cancellation.js';
  22. import { canceled } from './errors.js';
  23. import { Emitter, Event } from './event.js';
  24. import { toDisposable } from './lifecycle.js';
  25. import { setTimeout0 } from './platform.js';
  26. export function isThenable(obj) {
  27. return !!obj && typeof obj.then === 'function';
  28. }
  29. export function createCancelablePromise(callback) {
  30. const source = new CancellationTokenSource();
  31. const thenable = callback(source.token);
  32. const promise = new Promise((resolve, reject) => {
  33. const subscription = source.token.onCancellationRequested(() => {
  34. subscription.dispose();
  35. source.dispose();
  36. reject(canceled());
  37. });
  38. Promise.resolve(thenable).then(value => {
  39. subscription.dispose();
  40. source.dispose();
  41. resolve(value);
  42. }, err => {
  43. subscription.dispose();
  44. source.dispose();
  45. reject(err);
  46. });
  47. });
  48. return new class {
  49. cancel() {
  50. source.cancel();
  51. }
  52. then(resolve, reject) {
  53. return promise.then(resolve, reject);
  54. }
  55. catch(reject) {
  56. return this.then(undefined, reject);
  57. }
  58. finally(onfinally) {
  59. return promise.finally(onfinally);
  60. }
  61. };
  62. }
  63. export function raceCancellation(promise, token, defaultValue) {
  64. return Promise.race([promise, new Promise(resolve => token.onCancellationRequested(() => resolve(defaultValue)))]);
  65. }
  66. /**
  67. * A helper to prevent accumulation of sequential async tasks.
  68. *
  69. * Imagine a mail man with the sole task of delivering letters. As soon as
  70. * a letter submitted for delivery, he drives to the destination, delivers it
  71. * and returns to his base. Imagine that during the trip, N more letters were submitted.
  72. * When the mail man returns, he picks those N letters and delivers them all in a
  73. * single trip. Even though N+1 submissions occurred, only 2 deliveries were made.
  74. *
  75. * The throttler implements this via the queue() method, by providing it a task
  76. * factory. Following the example:
  77. *
  78. * const throttler = new Throttler();
  79. * const letters = [];
  80. *
  81. * function deliver() {
  82. * const lettersToDeliver = letters;
  83. * letters = [];
  84. * return makeTheTrip(lettersToDeliver);
  85. * }
  86. *
  87. * function onLetterReceived(l) {
  88. * letters.push(l);
  89. * throttler.queue(deliver);
  90. * }
  91. */
  92. export class Throttler {
  93. constructor() {
  94. this.activePromise = null;
  95. this.queuedPromise = null;
  96. this.queuedPromiseFactory = null;
  97. }
  98. queue(promiseFactory) {
  99. if (this.activePromise) {
  100. this.queuedPromiseFactory = promiseFactory;
  101. if (!this.queuedPromise) {
  102. const onComplete = () => {
  103. this.queuedPromise = null;
  104. const result = this.queue(this.queuedPromiseFactory);
  105. this.queuedPromiseFactory = null;
  106. return result;
  107. };
  108. this.queuedPromise = new Promise(resolve => {
  109. this.activePromise.then(onComplete, onComplete).then(resolve);
  110. });
  111. }
  112. return new Promise((resolve, reject) => {
  113. this.queuedPromise.then(resolve, reject);
  114. });
  115. }
  116. this.activePromise = promiseFactory();
  117. return new Promise((resolve, reject) => {
  118. this.activePromise.then((result) => {
  119. this.activePromise = null;
  120. resolve(result);
  121. }, (err) => {
  122. this.activePromise = null;
  123. reject(err);
  124. });
  125. });
  126. }
  127. }
  128. /**
  129. * A helper to delay (debounce) execution of a task that is being requested often.
  130. *
  131. * Following the throttler, now imagine the mail man wants to optimize the number of
  132. * trips proactively. The trip itself can be long, so he decides not to make the trip
  133. * as soon as a letter is submitted. Instead he waits a while, in case more
  134. * letters are submitted. After said waiting period, if no letters were submitted, he
  135. * decides to make the trip. Imagine that N more letters were submitted after the first
  136. * one, all within a short period of time between each other. Even though N+1
  137. * submissions occurred, only 1 delivery was made.
  138. *
  139. * The delayer offers this behavior via the trigger() method, into which both the task
  140. * to be executed and the waiting period (delay) must be passed in as arguments. Following
  141. * the example:
  142. *
  143. * const delayer = new Delayer(WAITING_PERIOD);
  144. * const letters = [];
  145. *
  146. * function letterReceived(l) {
  147. * letters.push(l);
  148. * delayer.trigger(() => { return makeTheTrip(); });
  149. * }
  150. */
  151. export class Delayer {
  152. constructor(defaultDelay) {
  153. this.defaultDelay = defaultDelay;
  154. this.timeout = null;
  155. this.completionPromise = null;
  156. this.doResolve = null;
  157. this.doReject = null;
  158. this.task = null;
  159. }
  160. trigger(task, delay = this.defaultDelay) {
  161. this.task = task;
  162. this.cancelTimeout();
  163. if (!this.completionPromise) {
  164. this.completionPromise = new Promise((resolve, reject) => {
  165. this.doResolve = resolve;
  166. this.doReject = reject;
  167. }).then(() => {
  168. this.completionPromise = null;
  169. this.doResolve = null;
  170. if (this.task) {
  171. const task = this.task;
  172. this.task = null;
  173. return task();
  174. }
  175. return undefined;
  176. });
  177. }
  178. this.timeout = setTimeout(() => {
  179. this.timeout = null;
  180. if (this.doResolve) {
  181. this.doResolve(null);
  182. }
  183. }, delay);
  184. return this.completionPromise;
  185. }
  186. isTriggered() {
  187. return this.timeout !== null;
  188. }
  189. cancel() {
  190. this.cancelTimeout();
  191. if (this.completionPromise) {
  192. if (this.doReject) {
  193. this.doReject(canceled());
  194. }
  195. this.completionPromise = null;
  196. }
  197. }
  198. cancelTimeout() {
  199. if (this.timeout !== null) {
  200. clearTimeout(this.timeout);
  201. this.timeout = null;
  202. }
  203. }
  204. dispose() {
  205. this.cancel();
  206. }
  207. }
  208. /**
  209. * A helper to delay execution of a task that is being requested often, while
  210. * preventing accumulation of consecutive executions, while the task runs.
  211. *
  212. * The mail man is clever and waits for a certain amount of time, before going
  213. * out to deliver letters. While the mail man is going out, more letters arrive
  214. * and can only be delivered once he is back. Once he is back the mail man will
  215. * do one more trip to deliver the letters that have accumulated while he was out.
  216. */
  217. export class ThrottledDelayer {
  218. constructor(defaultDelay) {
  219. this.delayer = new Delayer(defaultDelay);
  220. this.throttler = new Throttler();
  221. }
  222. trigger(promiseFactory, delay) {
  223. return this.delayer.trigger(() => this.throttler.queue(promiseFactory), delay);
  224. }
  225. dispose() {
  226. this.delayer.dispose();
  227. }
  228. }
  229. export function timeout(millis, token) {
  230. if (!token) {
  231. return createCancelablePromise(token => timeout(millis, token));
  232. }
  233. return new Promise((resolve, reject) => {
  234. const handle = setTimeout(() => {
  235. disposable.dispose();
  236. resolve();
  237. }, millis);
  238. const disposable = token.onCancellationRequested(() => {
  239. clearTimeout(handle);
  240. disposable.dispose();
  241. reject(canceled());
  242. });
  243. });
  244. }
  245. export function disposableTimeout(handler, timeout = 0) {
  246. const timer = setTimeout(handler, timeout);
  247. return toDisposable(() => clearTimeout(timer));
  248. }
  249. export function first(promiseFactories, shouldStop = t => !!t, defaultValue = null) {
  250. let index = 0;
  251. const len = promiseFactories.length;
  252. const loop = () => {
  253. if (index >= len) {
  254. return Promise.resolve(defaultValue);
  255. }
  256. const factory = promiseFactories[index++];
  257. const promise = Promise.resolve(factory());
  258. return promise.then(result => {
  259. if (shouldStop(result)) {
  260. return Promise.resolve(result);
  261. }
  262. return loop();
  263. });
  264. };
  265. return loop();
  266. }
  267. export class TimeoutTimer {
  268. constructor(runner, timeout) {
  269. this._token = -1;
  270. if (typeof runner === 'function' && typeof timeout === 'number') {
  271. this.setIfNotSet(runner, timeout);
  272. }
  273. }
  274. dispose() {
  275. this.cancel();
  276. }
  277. cancel() {
  278. if (this._token !== -1) {
  279. clearTimeout(this._token);
  280. this._token = -1;
  281. }
  282. }
  283. cancelAndSet(runner, timeout) {
  284. this.cancel();
  285. this._token = setTimeout(() => {
  286. this._token = -1;
  287. runner();
  288. }, timeout);
  289. }
  290. setIfNotSet(runner, timeout) {
  291. if (this._token !== -1) {
  292. // timer is already set
  293. return;
  294. }
  295. this._token = setTimeout(() => {
  296. this._token = -1;
  297. runner();
  298. }, timeout);
  299. }
  300. }
  301. export class IntervalTimer {
  302. constructor() {
  303. this._token = -1;
  304. }
  305. dispose() {
  306. this.cancel();
  307. }
  308. cancel() {
  309. if (this._token !== -1) {
  310. clearInterval(this._token);
  311. this._token = -1;
  312. }
  313. }
  314. cancelAndSet(runner, interval) {
  315. this.cancel();
  316. this._token = setInterval(() => {
  317. runner();
  318. }, interval);
  319. }
  320. }
  321. export class RunOnceScheduler {
  322. constructor(runner, delay) {
  323. this.timeoutToken = -1;
  324. this.runner = runner;
  325. this.timeout = delay;
  326. this.timeoutHandler = this.onTimeout.bind(this);
  327. }
  328. /**
  329. * Dispose RunOnceScheduler
  330. */
  331. dispose() {
  332. this.cancel();
  333. this.runner = null;
  334. }
  335. /**
  336. * Cancel current scheduled runner (if any).
  337. */
  338. cancel() {
  339. if (this.isScheduled()) {
  340. clearTimeout(this.timeoutToken);
  341. this.timeoutToken = -1;
  342. }
  343. }
  344. /**
  345. * Cancel previous runner (if any) & schedule a new runner.
  346. */
  347. schedule(delay = this.timeout) {
  348. this.cancel();
  349. this.timeoutToken = setTimeout(this.timeoutHandler, delay);
  350. }
  351. get delay() {
  352. return this.timeout;
  353. }
  354. set delay(value) {
  355. this.timeout = value;
  356. }
  357. /**
  358. * Returns true if scheduled.
  359. */
  360. isScheduled() {
  361. return this.timeoutToken !== -1;
  362. }
  363. onTimeout() {
  364. this.timeoutToken = -1;
  365. if (this.runner) {
  366. this.doRun();
  367. }
  368. }
  369. doRun() {
  370. if (this.runner) {
  371. this.runner();
  372. }
  373. }
  374. }
  375. /**
  376. * Execute the callback the next time the browser is idle
  377. */
  378. export let runWhenIdle;
  379. (function () {
  380. if (typeof requestIdleCallback !== 'function' || typeof cancelIdleCallback !== 'function') {
  381. runWhenIdle = (runner) => {
  382. setTimeout0(() => {
  383. if (disposed) {
  384. return;
  385. }
  386. const end = Date.now() + 3; // yield often
  387. runner(Object.freeze({
  388. didTimeout: true,
  389. timeRemaining() {
  390. return Math.max(0, end - Date.now());
  391. }
  392. }));
  393. });
  394. let disposed = false;
  395. return {
  396. dispose() {
  397. if (disposed) {
  398. return;
  399. }
  400. disposed = true;
  401. }
  402. };
  403. };
  404. }
  405. else {
  406. runWhenIdle = (runner, timeout) => {
  407. const handle = requestIdleCallback(runner, typeof timeout === 'number' ? { timeout } : undefined);
  408. let disposed = false;
  409. return {
  410. dispose() {
  411. if (disposed) {
  412. return;
  413. }
  414. disposed = true;
  415. cancelIdleCallback(handle);
  416. }
  417. };
  418. };
  419. }
  420. })();
  421. /**
  422. * An implementation of the "idle-until-urgent"-strategy as introduced
  423. * here: https://philipwalton.com/articles/idle-until-urgent/
  424. */
  425. export class IdleValue {
  426. constructor(executor) {
  427. this._didRun = false;
  428. this._executor = () => {
  429. try {
  430. this._value = executor();
  431. }
  432. catch (err) {
  433. this._error = err;
  434. }
  435. finally {
  436. this._didRun = true;
  437. }
  438. };
  439. this._handle = runWhenIdle(() => this._executor());
  440. }
  441. dispose() {
  442. this._handle.dispose();
  443. }
  444. get value() {
  445. if (!this._didRun) {
  446. this._handle.dispose();
  447. this._executor();
  448. }
  449. if (this._error) {
  450. throw this._error;
  451. }
  452. return this._value;
  453. }
  454. get isInitialized() {
  455. return this._didRun;
  456. }
  457. }
  458. /**
  459. * Creates a promise whose resolution or rejection can be controlled imperatively.
  460. */
  461. export class DeferredPromise {
  462. constructor() {
  463. this.resolved = false;
  464. this.p = new Promise((c, e) => {
  465. this.completeCallback = c;
  466. this.errorCallback = e;
  467. });
  468. }
  469. complete(value) {
  470. return new Promise(resolve => {
  471. this.completeCallback(value);
  472. this.resolved = true;
  473. resolve();
  474. });
  475. }
  476. }
  477. //#endregion
  478. //#region Promises
  479. export var Promises;
  480. (function (Promises) {
  481. /**
  482. * A drop-in replacement for `Promise.all` with the only difference
  483. * that the method awaits every promise to either fulfill or reject.
  484. *
  485. * Similar to `Promise.all`, only the first error will be returned
  486. * if any.
  487. */
  488. function settled(promises) {
  489. return __awaiter(this, void 0, void 0, function* () {
  490. let firstError = undefined;
  491. const result = yield Promise.all(promises.map(promise => promise.then(value => value, error => {
  492. if (!firstError) {
  493. firstError = error;
  494. }
  495. return undefined; // do not rethrow so that other promises can settle
  496. })));
  497. if (typeof firstError !== 'undefined') {
  498. throw firstError;
  499. }
  500. return result; // cast is needed and protected by the `throw` above
  501. });
  502. }
  503. Promises.settled = settled;
  504. /**
  505. * A helper to create a new `Promise<T>` with a body that is a promise
  506. * itself. By default, an error that raises from the async body will
  507. * end up as a unhandled rejection, so this utility properly awaits the
  508. * body and rejects the promise as a normal promise does without async
  509. * body.
  510. *
  511. * This method should only be used in rare cases where otherwise `async`
  512. * cannot be used (e.g. when callbacks are involved that require this).
  513. */
  514. function withAsyncBody(bodyFn) {
  515. // eslint-disable-next-line no-async-promise-executor
  516. return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
  517. try {
  518. yield bodyFn(resolve, reject);
  519. }
  520. catch (error) {
  521. reject(error);
  522. }
  523. }));
  524. }
  525. Promises.withAsyncBody = withAsyncBody;
  526. })(Promises || (Promises = {}));
  527. /**
  528. * A rich implementation for an `AsyncIterable<T>`.
  529. */
  530. export class AsyncIterableObject {
  531. constructor(executor) {
  532. this._state = 0 /* Initial */;
  533. this._results = [];
  534. this._error = null;
  535. this._onStateChanged = new Emitter();
  536. queueMicrotask(() => __awaiter(this, void 0, void 0, function* () {
  537. const writer = {
  538. emitOne: (item) => this.emitOne(item),
  539. emitMany: (items) => this.emitMany(items),
  540. reject: (error) => this.reject(error)
  541. };
  542. try {
  543. yield Promise.resolve(executor(writer));
  544. this.resolve();
  545. }
  546. catch (err) {
  547. this.reject(err);
  548. }
  549. finally {
  550. writer.emitOne = undefined;
  551. writer.emitMany = undefined;
  552. writer.reject = undefined;
  553. }
  554. }));
  555. }
  556. static fromArray(items) {
  557. return new AsyncIterableObject((writer) => {
  558. writer.emitMany(items);
  559. });
  560. }
  561. static fromPromise(promise) {
  562. return new AsyncIterableObject((emitter) => __awaiter(this, void 0, void 0, function* () {
  563. emitter.emitMany(yield promise);
  564. }));
  565. }
  566. static fromPromises(promises) {
  567. return new AsyncIterableObject((emitter) => __awaiter(this, void 0, void 0, function* () {
  568. yield Promise.all(promises.map((p) => __awaiter(this, void 0, void 0, function* () { return emitter.emitOne(yield p); })));
  569. }));
  570. }
  571. static merge(iterables) {
  572. return new AsyncIterableObject((emitter) => __awaiter(this, void 0, void 0, function* () {
  573. yield Promise.all(iterables.map((iterable) => { var iterable_1, iterable_1_1; return __awaiter(this, void 0, void 0, function* () {
  574. var e_1, _a;
  575. try {
  576. for (iterable_1 = __asyncValues(iterable); iterable_1_1 = yield iterable_1.next(), !iterable_1_1.done;) {
  577. const item = iterable_1_1.value;
  578. emitter.emitOne(item);
  579. }
  580. }
  581. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  582. finally {
  583. try {
  584. if (iterable_1_1 && !iterable_1_1.done && (_a = iterable_1.return)) yield _a.call(iterable_1);
  585. }
  586. finally { if (e_1) throw e_1.error; }
  587. }
  588. }); }));
  589. }));
  590. }
  591. [Symbol.asyncIterator]() {
  592. let i = 0;
  593. return {
  594. next: () => __awaiter(this, void 0, void 0, function* () {
  595. do {
  596. if (this._state === 2 /* DoneError */) {
  597. throw this._error;
  598. }
  599. if (i < this._results.length) {
  600. return { done: false, value: this._results[i++] };
  601. }
  602. if (this._state === 1 /* DoneOK */) {
  603. return { done: true, value: undefined };
  604. }
  605. yield Event.toPromise(this._onStateChanged.event);
  606. } while (true);
  607. })
  608. };
  609. }
  610. static map(iterable, mapFn) {
  611. return new AsyncIterableObject((emitter) => __awaiter(this, void 0, void 0, function* () {
  612. var e_2, _a;
  613. try {
  614. for (var iterable_2 = __asyncValues(iterable), iterable_2_1; iterable_2_1 = yield iterable_2.next(), !iterable_2_1.done;) {
  615. const item = iterable_2_1.value;
  616. emitter.emitOne(mapFn(item));
  617. }
  618. }
  619. catch (e_2_1) { e_2 = { error: e_2_1 }; }
  620. finally {
  621. try {
  622. if (iterable_2_1 && !iterable_2_1.done && (_a = iterable_2.return)) yield _a.call(iterable_2);
  623. }
  624. finally { if (e_2) throw e_2.error; }
  625. }
  626. }));
  627. }
  628. map(mapFn) {
  629. return AsyncIterableObject.map(this, mapFn);
  630. }
  631. static filter(iterable, filterFn) {
  632. return new AsyncIterableObject((emitter) => __awaiter(this, void 0, void 0, function* () {
  633. var e_3, _a;
  634. try {
  635. for (var iterable_3 = __asyncValues(iterable), iterable_3_1; iterable_3_1 = yield iterable_3.next(), !iterable_3_1.done;) {
  636. const item = iterable_3_1.value;
  637. if (filterFn(item)) {
  638. emitter.emitOne(item);
  639. }
  640. }
  641. }
  642. catch (e_3_1) { e_3 = { error: e_3_1 }; }
  643. finally {
  644. try {
  645. if (iterable_3_1 && !iterable_3_1.done && (_a = iterable_3.return)) yield _a.call(iterable_3);
  646. }
  647. finally { if (e_3) throw e_3.error; }
  648. }
  649. }));
  650. }
  651. filter(filterFn) {
  652. return AsyncIterableObject.filter(this, filterFn);
  653. }
  654. static coalesce(iterable) {
  655. return AsyncIterableObject.filter(iterable, item => !!item);
  656. }
  657. coalesce() {
  658. return AsyncIterableObject.coalesce(this);
  659. }
  660. static toPromise(iterable) {
  661. var iterable_4, iterable_4_1;
  662. var e_4, _a;
  663. return __awaiter(this, void 0, void 0, function* () {
  664. const result = [];
  665. try {
  666. for (iterable_4 = __asyncValues(iterable); iterable_4_1 = yield iterable_4.next(), !iterable_4_1.done;) {
  667. const item = iterable_4_1.value;
  668. result.push(item);
  669. }
  670. }
  671. catch (e_4_1) { e_4 = { error: e_4_1 }; }
  672. finally {
  673. try {
  674. if (iterable_4_1 && !iterable_4_1.done && (_a = iterable_4.return)) yield _a.call(iterable_4);
  675. }
  676. finally { if (e_4) throw e_4.error; }
  677. }
  678. return result;
  679. });
  680. }
  681. toPromise() {
  682. return AsyncIterableObject.toPromise(this);
  683. }
  684. /**
  685. * The value will be appended at the end.
  686. *
  687. * **NOTE** If `resolve()` or `reject()` have already been called, this method has no effect.
  688. */
  689. emitOne(value) {
  690. if (this._state !== 0 /* Initial */) {
  691. return;
  692. }
  693. // it is important to add new values at the end,
  694. // as we may have iterators already running on the array
  695. this._results.push(value);
  696. this._onStateChanged.fire();
  697. }
  698. /**
  699. * The values will be appended at the end.
  700. *
  701. * **NOTE** If `resolve()` or `reject()` have already been called, this method has no effect.
  702. */
  703. emitMany(values) {
  704. if (this._state !== 0 /* Initial */) {
  705. return;
  706. }
  707. // it is important to add new values at the end,
  708. // as we may have iterators already running on the array
  709. this._results = this._results.concat(values);
  710. this._onStateChanged.fire();
  711. }
  712. /**
  713. * Calling `resolve()` will mark the result array as complete.
  714. *
  715. * **NOTE** `resolve()` must be called, otherwise all consumers of this iterable will hang indefinitely, similar to a non-resolved promise.
  716. * **NOTE** If `resolve()` or `reject()` have already been called, this method has no effect.
  717. */
  718. resolve() {
  719. if (this._state !== 0 /* Initial */) {
  720. return;
  721. }
  722. this._state = 1 /* DoneOK */;
  723. this._onStateChanged.fire();
  724. }
  725. /**
  726. * Writing an error will permanently invalidate this iterable.
  727. * The current users will receive an error thrown, as will all future users.
  728. *
  729. * **NOTE** If `resolve()` or `reject()` have already been called, this method has no effect.
  730. */
  731. reject(error) {
  732. if (this._state !== 0 /* Initial */) {
  733. return;
  734. }
  735. this._state = 2 /* DoneError */;
  736. this._error = error;
  737. this._onStateChanged.fire();
  738. }
  739. }
  740. AsyncIterableObject.EMPTY = AsyncIterableObject.fromArray([]);
  741. export class CancelableAsyncIterableObject extends AsyncIterableObject {
  742. constructor(_source, executor) {
  743. super(executor);
  744. this._source = _source;
  745. }
  746. cancel() {
  747. this._source.cancel();
  748. }
  749. }
  750. export function createCancelableAsyncIterable(callback) {
  751. const source = new CancellationTokenSource();
  752. const innerIterable = callback(source.token);
  753. return new CancelableAsyncIterableObject(source, (emitter) => __awaiter(this, void 0, void 0, function* () {
  754. var e_5, _a;
  755. const subscription = source.token.onCancellationRequested(() => {
  756. subscription.dispose();
  757. source.dispose();
  758. emitter.reject(canceled());
  759. });
  760. try {
  761. try {
  762. for (var innerIterable_1 = __asyncValues(innerIterable), innerIterable_1_1; innerIterable_1_1 = yield innerIterable_1.next(), !innerIterable_1_1.done;) {
  763. const item = innerIterable_1_1.value;
  764. if (source.token.isCancellationRequested) {
  765. // canceled in the meantime
  766. return;
  767. }
  768. emitter.emitOne(item);
  769. }
  770. }
  771. catch (e_5_1) { e_5 = { error: e_5_1 }; }
  772. finally {
  773. try {
  774. if (innerIterable_1_1 && !innerIterable_1_1.done && (_a = innerIterable_1.return)) yield _a.call(innerIterable_1);
  775. }
  776. finally { if (e_5) throw e_5.error; }
  777. }
  778. subscription.dispose();
  779. source.dispose();
  780. }
  781. catch (err) {
  782. subscription.dispose();
  783. source.dispose();
  784. emitter.reject(err);
  785. }
  786. }));
  787. }
  788. //#endregion