@handy-common-utils/promise-utils
Advanced tools
Comparing version 1.0.5 to 1.0.6
declare type InParrellelResult<T> = T extends void ? void : Array<T>; | ||
export declare enum PromiseState { | ||
Pending = "Pending", | ||
Fulfilled = "Fulfilled", | ||
Rejected = "Rejected" | ||
} | ||
export declare abstract class PromiseUtils { | ||
@@ -86,2 +91,20 @@ /** | ||
static timeoutReject<T>(operation: Promise<T>, ms: number, rejectReason: any): Promise<T>; | ||
/** | ||
* Get the state of the Promise. | ||
* Please note that the returned value is a Promise, although it resolves immediately. | ||
* @param p the Promise for which we would like to know its state | ||
* @return A Promise that resolves immediately cotaining the state of the input Promise | ||
*/ | ||
static promiseState(p: Promise<any>): Promise<PromiseState>; | ||
private static synchronizationLocks; | ||
/** | ||
* Equivalent of `synchronized` in Java. | ||
* In any situation there's no concurrent execution of any operation function associated with the same lock. | ||
* The operation function has access to the state (when `synchronized` is called), settledState (when the operation function is called), and result of the previous operation. | ||
* In case there is no previous invocation, state, settledState and result would all be undefined. | ||
* @param lock the object (could be a string, a number, or `this` in a class) that is used to apply the lock | ||
* @param operation function for doing the computation and returning a Promise | ||
* @returns the result of the operation function | ||
*/ | ||
static synchronized<T>(lock: any, operation: (previousState: PromiseState | undefined, previousSettledState: PromiseState | undefined, previousResult: any) => Promise<T>): Promise<T>; | ||
} | ||
@@ -94,3 +117,5 @@ export declare const repeat: typeof PromiseUtils.repeat; | ||
export declare const timeoutReject: typeof PromiseUtils.timeoutReject; | ||
export declare const synchronized: typeof PromiseUtils.synchronized; | ||
export declare const promiseState: typeof PromiseUtils.promiseState; | ||
export {}; | ||
//# sourceMappingURL=promise-utils.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.timeoutReject = exports.timeoutResolve = exports.delayedReject = exports.delayedResolve = exports.inParallel = exports.repeat = exports.PromiseUtils = void 0; | ||
exports.promiseState = exports.synchronized = exports.timeoutReject = exports.timeoutResolve = exports.delayedReject = exports.delayedResolve = exports.inParallel = exports.repeat = exports.PromiseUtils = exports.PromiseState = void 0; | ||
var PromiseState; | ||
(function (PromiseState) { | ||
PromiseState["Pending"] = "Pending"; | ||
PromiseState["Fulfilled"] = "Fulfilled"; | ||
PromiseState["Rejected"] = "Rejected"; | ||
})(PromiseState = exports.PromiseState || (exports.PromiseState = {})); | ||
class PromiseUtils { | ||
@@ -132,4 +138,46 @@ /** | ||
} | ||
/** | ||
* Get the state of the Promise. | ||
* Please note that the returned value is a Promise, although it resolves immediately. | ||
* @param p the Promise for which we would like to know its state | ||
* @return A Promise that resolves immediately cotaining the state of the input Promise | ||
*/ | ||
static promiseState(p) { | ||
const t = {}; | ||
return Promise.race([p, t]) | ||
.then(v => (v === t) ? PromiseState.Pending : PromiseState.Fulfilled, () => PromiseState.Rejected); | ||
} | ||
/** | ||
* Equivalent of `synchronized` in Java. | ||
* In any situation there's no concurrent execution of any operation function associated with the same lock. | ||
* The operation function has access to the state (when `synchronized` is called), settledState (when the operation function is called), and result of the previous operation. | ||
* In case there is no previous invocation, state, settledState and result would all be undefined. | ||
* @param lock the object (could be a string, a number, or `this` in a class) that is used to apply the lock | ||
* @param operation function for doing the computation and returning a Promise | ||
* @returns the result of the operation function | ||
*/ | ||
static async synchronized(lock, operation) { | ||
let resultPromise; | ||
const previousResultPromise = PromiseUtils.synchronizationLocks.get(lock); | ||
let previousState; | ||
if (previousResultPromise !== undefined) { | ||
previousState = await PromiseUtils.promiseState(previousResultPromise); | ||
} | ||
switch (previousState) { | ||
case PromiseState.Pending: // concurrency | ||
resultPromise = previousResultPromise.then(result => operation(PromiseState.Pending, PromiseState.Fulfilled, result), reason => operation(PromiseState.Pending, PromiseState.Rejected, reason)); | ||
break; | ||
case undefined: // no concurrency and no history | ||
resultPromise = operation(undefined, undefined, undefined); | ||
break; | ||
default: // no concurrency but with history | ||
resultPromise = operation(previousState, previousState, await previousResultPromise.catch(error => error)); | ||
break; | ||
} | ||
PromiseUtils.synchronizationLocks.set(lock, resultPromise); | ||
return resultPromise; | ||
} | ||
} | ||
exports.PromiseUtils = PromiseUtils; | ||
PromiseUtils.synchronizationLocks = new Map(); | ||
exports.repeat = PromiseUtils.repeat; | ||
@@ -141,1 +189,3 @@ exports.inParallel = PromiseUtils.inParallel; | ||
exports.timeoutReject = PromiseUtils.timeoutReject; | ||
exports.synchronized = PromiseUtils.synchronized; | ||
exports.promiseState = PromiseUtils.promiseState; |
{ | ||
"name": "@handy-common-utils/promise-utils", | ||
"version": "1.0.5", | ||
"version": "1.0.6", | ||
"description": "Promise related utilities", | ||
@@ -8,3 +8,3 @@ "scripts": { | ||
"test": "nyc mocha -r ts-node/register test/**/*.spec.ts", | ||
"prepare": "shx rm -rf dist && tsc", | ||
"prepare": "shx rm -rf dist && tsc && es-check", | ||
"preversion": "generate-api-docs-and-update-readme && git add README.md" | ||
@@ -21,3 +21,4 @@ }, | ||
"devDependencies": { | ||
"@handy-common-utils/dev-dependencies": "^1.0.10" | ||
"@handy-common-utils/dev-dependencies": "^1.0.11", | ||
"es-check": "^5.1.2" | ||
}, | ||
@@ -24,0 +25,0 @@ "publishConfig": { |
104
README.md
@@ -50,2 +50,6 @@ # @handy-common-utils/promise-utils | ||
#### Enumerations | ||
* [PromiseState](#enumspromisestatemd) | ||
#### Classes | ||
@@ -64,3 +68,5 @@ | ||
* [inParallel](#inparallel) | ||
* [promiseState](#promisestate) | ||
* [repeat](#repeat) | ||
* [synchronized](#synchronized) | ||
* [timeoutReject](#timeoutreject) | ||
@@ -101,2 +107,8 @@ * [timeoutResolve](#timeoutresolve) | ||
#### promiseState | ||
• `Const` **promiseState**: [promiseState](#promisestate) = PromiseUtils.promiseState | ||
___ | ||
#### repeat | ||
@@ -108,2 +120,8 @@ | ||
#### synchronized | ||
• `Const` **synchronized**: [synchronized](#synchronized) = PromiseUtils.synchronized | ||
___ | ||
#### timeoutReject | ||
@@ -141,3 +159,5 @@ | ||
* [inParallel](#inparallel) | ||
* [promiseState](#promisestate) | ||
* [repeat](#repeat) | ||
* [synchronized](#synchronized) | ||
* [timeoutReject](#timeoutreject) | ||
@@ -239,2 +259,21 @@ * [timeoutResolve](#timeoutresolve) | ||
##### promiseState | ||
▸ `Static` **promiseState**(`p`: Promise\<any>): Promise\<[PromiseState](#enumspromisestatemd)> | ||
Get the state of the Promise. | ||
Please note that the returned value is a Promise, although it resolves immediately. | ||
###### Parameters: | ||
Name | Type | Description | | ||
------ | ------ | ------ | | ||
`p` | Promise\<any> | the Promise for which we would like to know its state | | ||
**Returns:** Promise\<[PromiseState](#enumspromisestatemd)> | ||
A Promise that resolves immediately cotaining the state of the input Promise | ||
___ | ||
##### repeat | ||
@@ -282,2 +321,30 @@ | ||
##### synchronized | ||
▸ `Static` **synchronized**\<T>(`lock`: any, `operation`: (previousState: [PromiseState](#enumspromisestatemd) \| undefined, previousSettledState: [PromiseState](#enumspromisestatemd) \| undefined, previousResult: any) => Promise\<T>): Promise\<T> | ||
Equivalent of `synchronized` in Java. | ||
In any situation there's no concurrent execution of any operation function associated with the same lock. | ||
The operation function has access to the state (when `synchronized` is called), settledState (when the operation function is called), and result of the previous operation. | ||
In case there is no previous invocation, state, settledState and result would all be undefined. | ||
###### Type parameters: | ||
Name | | ||
------ | | ||
`T` | | ||
###### Parameters: | ||
Name | Type | Description | | ||
------ | ------ | ------ | | ||
`lock` | any | the object (could be a string, a number, or `this` in a class) that is used to apply the lock | | ||
`operation` | (previousState: [PromiseState](#enumspromisestatemd) \| undefined, previousSettledState: [PromiseState](#enumspromisestatemd) \| undefined, previousResult: any) => Promise\<T> | function for doing the computation and returning a Promise | | ||
**Returns:** Promise\<T> | ||
the result of the operation function | ||
___ | ||
##### timeoutReject | ||
@@ -334,2 +401,39 @@ | ||
the new Promise that resolves to the specified result in case timeout happens | ||
## Enums | ||
<a name="enumspromisestatemd"></a> | ||
**[@handy-common-utils/promise-utils](#readmemd)** | ||
> [Globals](#readmemd) / PromiseState | ||
### Enumeration: PromiseState | ||
#### Index | ||
##### Enumeration members | ||
* [Fulfilled](#fulfilled) | ||
* [Pending](#pending) | ||
* [Rejected](#rejected) | ||
#### Enumeration members | ||
##### Fulfilled | ||
• **Fulfilled**: = "Fulfilled" | ||
___ | ||
##### Pending | ||
• **Pending**: = "Pending" | ||
___ | ||
##### Rejected | ||
• **Rejected**: = "Rejected" | ||
<!-- API end --> |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
43717
308
432
2