microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
984ca036ea8e629228ba7ebe24a22b2ea2415fe1

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/common/node/promise.ts

86lines · 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 * as Q from "q";
5
6/**
7 * Utilities for working with promises.
8 */
9export class PromiseUtil {
10 public forEach<T>(sourcesMaybePromise: Q.Promise<T[]> | T[], promiseGenerator: (source: T) => Q.Promise<void>): Q.Promise<void> {
11 const sourcesPromise = <Q.Promise<T[]>>Q(sourcesMaybePromise);
12 return Q(sourcesPromise).then(sources => {
13 return Q.all(sources.map(source => {
14 return promiseGenerator(source);
15 })).then(() => { });
16 });
17 }
18
19 /**
20 * Retries an operation a given number of times. For each retry, a condition is checked.
21 * If the condition is not satisfied after the maximum number of retries, and error is thrown.
22 * Otherwise, the result of the operation is returned once the condition is satisfied.
23 *
24 * @param operation - the function to execute.
25 * @param condition - the condition to check between iterations.
26 * @param maxRetries - the maximum number of retries.
27 * @param delay - time between iterations, in milliseconds.
28 * @param failure - error description.
29 */
30 public retryAsync<T>(operation: () => Q.Promise<T>, condition: (result: T) => boolean | Q.Promise<boolean>, maxRetries: number, delay: number, failure: string): Q.Promise<T> {
31 return this.retryAsyncIteration(operation, condition, maxRetries, 0, delay, failure);
32 }
33
34 public retryAsyncPromise<T>(operation: () => Promise<T>, condition: (result: T) => boolean | Promise<boolean>, maxRetries: number, delay: number, failure: string): Promise<T> {
35 return this.retryAsyncIterationRawPromise(operation, condition, maxRetries, 0, delay, failure);
36 }
37
38 public reduce<T>(sources: T[]|Q.Promise<T[]>, generateAsyncOperation: (value: T) => Q.Promise<void>): Q.Promise<void> {
39 const promisedSources = <Q.Promise<T[]>>Q(sources);
40 return promisedSources.then(resolvedSources => {
41 return resolvedSources.reduce((previousReduction: Q.Promise<void>, newSource: T) => {
42 return previousReduction.then(() => {
43 return generateAsyncOperation(newSource);
44 });
45 }, Q<void>(void 0));
46 });
47 }
48
49 public delay(duration: number): Promise<void> {
50 return new Promise<void>(resolve => setTimeout(resolve, duration));
51 }
52
53 private retryAsyncIteration<T>(operation: () => Q.Promise<T>, condition: (result: T) => boolean | Q.Promise<boolean>, maxRetries: number, iteration: number, delay: number, failure: string): Q.Promise<T> {
54 return operation()
55 .then(result => {
56 return Q(result).then(condition).then((conditionResult => {
57 if (conditionResult) {
58 return result;
59 }
60
61 if (iteration < maxRetries) {
62 return Q.delay(delay).then(() => this.retryAsyncIteration(operation, condition, maxRetries, iteration + 1, delay, failure));
63 }
64
65 throw new Error(failure);
66 }));
67 });
68 }
69
70 private retryAsyncIterationRawPromise<T>(operation: () => Promise<T>, condition: (result: T) => boolean | Promise<boolean>, maxRetries: number, iteration: number, delay: number, failure: string): Promise<T> {
71 return operation()
72 .then(result => {
73 return Promise.resolve(result).then(condition).then((conditionResult => {
74 if (conditionResult) {
75 return result;
76 }
77
78 if (iteration < maxRetries) {
79 return this.delay(delay).then(() => this.retryAsyncIterationRawPromise(operation, condition, maxRetries, iteration + 1, delay, failure));
80 }
81
82 throw new Error(failure);
83 }));
84 });
85 }
86}