microsoft/vscode-react-native

Public

mirrored fromhttps://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
78c2aaee56e1edfea55cdebbdccbf5541dff7beb

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/common/node/promise.ts

117lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import { CancellationTokenSource } from "vscode";
5
6/**
7 * Utilities for working with promises.
8 */
9export class PromiseUtil {
10 public static async forEach<T>(
11 sources: T[],
12 promiseGenerator: (source: T) => Promise<void>,
13 ): Promise<void> {
14 await Promise.all(
15 sources.map(source => {
16 return promiseGenerator(source);
17 }),
18 );
19 }
20 /**
21 * Retries an operation a given number of times. For each retry, a condition is checked.
22 * If the condition is not satisfied after the maximum number of retries, and error is thrown.
23 * Otherwise, the result of the operation is returned once the condition is satisfied.
24 *
25 * @param operation - the function to execute.
26 * @param condition - the condition to check between iterations.
27 * @param maxRetries - the maximum number of retries.
28 * @param delay - time between iterations, in milliseconds.
29 * @param failure - error description.
30 */
31 public static retryAsync<T>(
32 operation: () => Promise<T>,
33 condition: (result: T) => boolean | Promise<boolean>,
34 maxRetries: number,
35 delay: number,
36 failure: string,
37 cancellationTokenSource?: CancellationTokenSource,
38 ): Promise<T> {
39 return this.retryAsyncIteration(
40 operation,
41 condition,
42 maxRetries,
43 0,
44 delay,
45 failure,
46 cancellationTokenSource,
47 );
48 }
49
50 public static async reduce<T>(
51 sources: T[] | Promise<T[]>,
52 generateAsyncOperation: (value: T) => Promise<void>,
53 ): Promise<void> {
54 let arraySources: T[];
55 if (sources instanceof Promise) {
56 arraySources = await sources;
57 } else {
58 arraySources = sources;
59 }
60
61 return arraySources.reduce(async (previousReduction: Promise<void>, newSource: T) => {
62 await previousReduction;
63 return generateAsyncOperation(newSource);
64 }, Promise.resolve());
65 }
66
67 public static async delay(duration: number): Promise<void> {
68 return new Promise<void>(resolve => setTimeout(resolve, duration));
69 }
70
71 public static promiseCacheDecorator<T>(
72 func: (...args: any[]) => Promise<T>,
73 context: Record<string, any> | null = null,
74 ): (...args: any[]) => Promise<T> {
75 let promise: Promise<T>;
76 return (...args: any[]): Promise<T> => {
77 if (!promise) {
78 promise = func.apply(context, args);
79 }
80 return promise;
81 };
82 }
83
84 private static async retryAsyncIteration<T>(
85 operation: () => Promise<T>,
86 condition: (result: T) => boolean | Promise<boolean>,
87 maxRetries: number,
88 iteration: number,
89 delay: number,
90 failure: string,
91 cancellationTokenSource?: CancellationTokenSource,
92 ): Promise<T> {
93 const result = await operation();
94 const conditionResult = await condition(result);
95 if (conditionResult) {
96 return result;
97 }
98
99 if (
100 iteration < maxRetries &&
101 !(cancellationTokenSource && cancellationTokenSource.token.isCancellationRequested)
102 ) {
103 await PromiseUtil.delay(delay);
104 return this.retryAsyncIteration(
105 operation,
106 condition,
107 maxRetries,
108 iteration + 1,
109 delay,
110 failure,
111 cancellationTokenSource,
112 );
113 }
114
115 throw new Error(failure);
116 }
117}
118