microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
892f0aa6d2f90a4b52e551b6b4c8270ed6b96e83

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/common/node/promise.ts

126lines · 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 forEach<T>(sources: T[], promiseGenerator: (source: T) => Promise<void>): Promise<void> {
11 return Promise.all(
12 sources.map(source => {
13 return promiseGenerator(source);
14 }),
15 ).then(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function
16 }
17 /**
18 * Retries an operation a given number of times. For each retry, a condition is checked.
19 * If the condition is not satisfied after the maximum number of retries, and error is thrown.
20 * Otherwise, the result of the operation is returned once the condition is satisfied.
21 *
22 * @param operation - the function to execute.
23 * @param condition - the condition to check between iterations.
24 * @param maxRetries - the maximum number of retries.
25 * @param delay - time between iterations, in milliseconds.
26 * @param failure - error description.
27 */
28 public retryAsync<T>(
29 operation: () => Promise<T>,
30 condition: (result: T) => boolean | Promise<boolean>,
31 maxRetries: number,
32 delay: number,
33 failure: string,
34 cancellationTokenSource?: CancellationTokenSource,
35 ): Promise<T> {
36 return this.retryAsyncIteration(
37 operation,
38 condition,
39 maxRetries,
40 0,
41 delay,
42 failure,
43 cancellationTokenSource,
44 );
45 }
46
47 public reduce<T>(
48 sources: T[] | Promise<T[]>,
49 generateAsyncOperation: (value: T) => Promise<void>,
50 ): Promise<void> {
51 let promisedSources: Promise<T[]>;
52 if (sources instanceof Promise) {
53 promisedSources = sources;
54 } else {
55 promisedSources = Promise.resolve(sources);
56 }
57 return promisedSources.then(resolvedSources => {
58 return resolvedSources.reduce((previousReduction: Promise<void>, newSource: T) => {
59 return previousReduction.then(() => {
60 return generateAsyncOperation(newSource);
61 });
62 }, Promise.resolve());
63 });
64 }
65
66 public static async delay(duration: number): Promise<void> {
67 return new Promise<void>(resolve => setTimeout(resolve, duration));
68 }
69
70 public static promiseCacheDecorator<T>(
71 func: (...args: any[]) => Promise<T>,
72 context: Record<string, any> | null = null,
73 ): (...args: any[]) => Promise<T> {
74 let promise: Promise<T>;
75 return (...args: any[]): Promise<T> => {
76 if (promise) {
77 return promise;
78 } else {
79 promise = func.apply(context, args);
80 return promise;
81 }
82 };
83 }
84
85 private retryAsyncIteration<T>(
86 operation: () => Promise<T>,
87 condition: (result: T) => boolean | Promise<boolean>,
88 maxRetries: number,
89 iteration: number,
90 delay: number,
91 failure: string,
92 cancellationTokenSource?: CancellationTokenSource,
93 ): Promise<T> {
94 return operation().then(result => {
95 return Promise.resolve(result)
96 .then(condition)
97 .then(conditionResult => {
98 if (conditionResult) {
99 return result;
100 }
101
102 if (
103 iteration < maxRetries &&
104 !(
105 cancellationTokenSource &&
106 cancellationTokenSource.token.isCancellationRequested
107 )
108 ) {
109 return PromiseUtil.delay(delay).then(() =>
110 this.retryAsyncIteration(
111 operation,
112 condition,
113 maxRetries,
114 iteration + 1,
115 delay,
116 failure,
117 cancellationTokenSource,
118 ),
119 );
120 }
121
122 throw new Error(failure);
123 });
124 });
125 }
126}
127