@jcoreio/async-throttle
Advanced tools
Comparing version 1.4.7 to 1.5.0
@@ -11,4 +11,5 @@ export class CanceledError extends Error {} | ||
(...args: Args): Promise<Value> | ||
invokeIgnoreResult: (...args: Args) => void | ||
cancel: () => Promise<void> | ||
flush: () => Promise<void> | ||
} |
@@ -73,5 +73,14 @@ "use strict"; | ||
function setNextArgs(args) { | ||
nextArgs = nextArgs ? getNextArgs(nextArgs, args) : args; | ||
if (!nextArgs) throw new Error('unexpected error: nextArgs is null'); | ||
} | ||
function doInvoke() { | ||
return nextInvocation = (delay || Promise.resolve()).then(invoke); | ||
} | ||
function wrapper(...args) { | ||
try { | ||
nextArgs = nextArgs ? getNextArgs(nextArgs, args) : args; | ||
setNextArgs(args); | ||
} catch (error) { | ||
@@ -81,7 +90,41 @@ return Promise.reject(error); | ||
if (!nextArgs) return Promise.reject(new Error('unexpected error: nextArgs is null')); | ||
if (nextInvocation) return nextInvocation; | ||
return nextInvocation = (delay || Promise.resolve()).then(invoke); | ||
return nextInvocation || doInvoke(); | ||
} | ||
/** | ||
* Calls the throttled function soon, but doesn't return a promise, catches | ||
* any CanceledError, and doesn't create any new promises if a call is already | ||
* pending. | ||
* | ||
* The throttled function should handle all errors internally, | ||
* e.g.: | ||
* | ||
* asyncThrottle(async () => { | ||
* try { | ||
* await foo() | ||
* } catch (err) { | ||
* // handle error | ||
* } | ||
* }) | ||
* | ||
* If the throttled function throws an error or returns a promise that is | ||
* eventually rejected, the runtime's unhandled promise rejection handler will | ||
* be called, which may crash the process, route the rejection to a handler | ||
* that has been previously registered, or ignore the rejection, depending | ||
* on the runtime and your code. | ||
*/ | ||
wrapper.invokeIgnoreResult = (...args) => { | ||
setNextArgs(args); | ||
if (!nextInvocation) { | ||
doInvoke().catch(err => { | ||
if (!(err instanceof CanceledError)) { | ||
// trigger the unhandled promise rejection handler | ||
throw err; | ||
} | ||
}); | ||
} | ||
}; | ||
wrapper.cancel = async () => { | ||
@@ -88,0 +131,0 @@ var _delay, _delay$cancel; |
@@ -11,4 +11,5 @@ export class CanceledError extends Error {} | ||
(...args: Args): Promise<Value> | ||
invokeIgnoreResult: (...args: Args) => void | ||
cancel: () => Promise<void> | ||
flush: () => Promise<void> | ||
} |
55
index.js
@@ -122,2 +122,11 @@ "use strict"; | ||
function setNextArgs(args) { | ||
nextArgs = nextArgs ? getNextArgs(nextArgs, args) : args; | ||
if (!nextArgs) throw new Error('unexpected error: nextArgs is null'); | ||
} | ||
function doInvoke() { | ||
return nextInvocation = (delay || Promise.resolve()).then(invoke); | ||
} | ||
function wrapper() { | ||
@@ -129,3 +138,3 @@ try { | ||
nextArgs = nextArgs ? getNextArgs(nextArgs, args) : args; | ||
setNextArgs(args); | ||
} catch (error) { | ||
@@ -135,7 +144,45 @@ return Promise.reject(error); | ||
if (!nextArgs) return Promise.reject(new Error('unexpected error: nextArgs is null')); | ||
if (nextInvocation) return nextInvocation; | ||
return nextInvocation = (delay || Promise.resolve()).then(invoke); | ||
return nextInvocation || doInvoke(); | ||
} | ||
/** | ||
* Calls the throttled function soon, but doesn't return a promise, catches | ||
* any CanceledError, and doesn't create any new promises if a call is already | ||
* pending. | ||
* | ||
* The throttled function should handle all errors internally, | ||
* e.g.: | ||
* | ||
* asyncThrottle(async () => { | ||
* try { | ||
* await foo() | ||
* } catch (err) { | ||
* // handle error | ||
* } | ||
* }) | ||
* | ||
* If the throttled function throws an error or returns a promise that is | ||
* eventually rejected, the runtime's unhandled promise rejection handler will | ||
* be called, which may crash the process, route the rejection to a handler | ||
* that has been previously registered, or ignore the rejection, depending | ||
* on the runtime and your code. | ||
*/ | ||
wrapper.invokeIgnoreResult = function () { | ||
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
} | ||
setNextArgs(args); | ||
if (!nextInvocation) { | ||
doInvoke()["catch"](function (err) { | ||
if (!(err instanceof CanceledError)) { | ||
// trigger the unhandled promise rejection handler | ||
throw err; | ||
} | ||
}); | ||
} | ||
}; | ||
wrapper.cancel = /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() { | ||
@@ -142,0 +189,0 @@ var _delay, _delay$cancel; |
{ | ||
"name": "@jcoreio/async-throttle", | ||
"version": "1.4.7", | ||
"version": "1.5.0", | ||
"description": "throttle async and promise-returning functions. Other packages don't do it right.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -72,2 +72,33 @@ # async-throttle | ||
### `throttledFn.invokeIgnoreResult(args)` | ||
Calls the throttled function soon, but doesn't return a promise, catches any CanceledError, and doesn't create any new promises if a call is already pending. | ||
To use this, you should handle all errors inside the throttled function: | ||
```js | ||
const throttled = throttle(async (arg) => { | ||
try { | ||
await doSomething(arg) | ||
} catch (err) { | ||
// handle error | ||
} | ||
}) | ||
``` | ||
Then call `invokeIgnoreResult` instead of the throttled function: | ||
```js | ||
throttled.invokeIgnoreResult(arg) | ||
``` | ||
The `invokeIgnoreResult` method is useful because the following code example would leave 1000 pending promises | ||
on the heap, even though the catch block is a no-op: | ||
```js | ||
for (let i = 0; i < 1000; i++) { | ||
throttled(arg).catch(() => {}) | ||
} | ||
``` | ||
### `throttledFn.cancel()` | ||
@@ -74,0 +105,0 @@ |
Sorry, the diff of this file is not supported yet
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
30962
339
117