Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

async-task-schedule

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

async-task-schedule - npm Package Compare versions

Comparing version 0.0.2 to 0.0.3

coverage/clover.xml

143

dist/index.es.js

@@ -5,5 +5,6 @@ class $d415641d0cfd8c85$export$2e2bcd8739ae039 {

*/ static defaultOptions = {
isSameTask: (a, b)=>a === b,
isSameTask: $d415641d0cfd8c85$export$2e2bcd8739ae039.isEqual,
taskExecStrategy: "parallel",
maxWaitingGap: 50,
invalidAfter: 1000,
taskWaitingStrategy: "debounce",

@@ -24,6 +25,5 @@ retryWhenFailed: true

this.maxWaitingGap = userOptions.maxWaitingGap;
// @ts-ignore
this.taskWaitingStrategy = userOptions.taskWaitingStrategy;
this.batchDoTasks = userOptions.batchDoTasks;
// @ts-ignore
if (!userOptions.batchDoTasks && !userOptions.doTask) throw new Error("one of batchDoTasks / doTask must be specified");
this.batchDoTasks = userOptions.batchDoTasks || $d415641d0cfd8c85$export$2e2bcd8739ae039.wrapDoTask(userOptions.doTask);
this.taskExecStrategy = userOptions.taskExecStrategy;

@@ -38,4 +38,4 @@ this.retryWhenFailed = userOptions.retryWhenFailed;

const result = this.tryGetTaskResult(tasks);
if (result instanceof Error) throw result;
return result;
if (result instanceof Error) return Promise.reject(result);
return Promise.resolve(result);
} catch (error) {

@@ -77,5 +77,9 @@ // not found

];
// 去除掉正在等待的、正在处理的以及已经成功的
// remove duplicated tasks in itself
myTasks = myTasks.filter((task, idx)=>idx === myTasks.findIndex((t)=>this.isSameTask(t, task)));
// remove pending tasks
if (this.pendingTasks.length) myTasks = myTasks.filter((f)=>!this.hasTask(this.pendingTasks, f));
// remove doing tasks
if (myTasks.length && this.doingTasks.length) myTasks = myTasks.filter((f)=>!this.hasTask(this.doingTasks, f));
// remove done tasks
if (myTasks.length) myTasks = myTasks.filter((f)=>!this.getTaskResult(f));

@@ -96,9 +100,9 @@ if (!myTasks.length) return;

* if taskExecStrategy is parallel then do it immediately,
* otherwise waiting util taskQueue is empty
* otherwise waiting util doingTasks is empty
*/ tryTodDoTasks() {
// should exec in serial, and still has executing tasks
if (this.taskExecStrategy === "serial" && this.taskQueue.length) {
if (this.taskExecStrategy === "serial" && this.doingTasks.length) {
clearTimeout(this.delayTimeoutId);
// wait a moment then check again
this.delayTimeoutId = setTimeout(this.tryTodDoTasks, 100);
this.delayTimeoutId = setTimeout(this.tryTodDoTasks, 50);
} else this.doTasks();

@@ -126,25 +130,17 @@ }

else {
try {
const allResponse = await Promise.all(tasksGroup.map((taskList)=>$d415641d0cfd8c85$export$2e2bcd8739ae039.wrapPromise(this.batchDoTasks(taskList))));
allResponse.forEach((result, index)=>{
this.updateResultMap(tasksGroup[index], // @ts-ignore
result.status === "rejected" ? $d415641d0cfd8c85$export$2e2bcd8739ae039.wrapError(result.reason) : result.value);
});
} catch (error1) {
this.updateResultMap(tasks, $d415641d0cfd8c85$export$2e2bcd8739ae039.wrapError(error1));
}
const allResponse = await Promise.all(tasksGroup.map((taskList)=>$d415641d0cfd8c85$export$2e2bcd8739ae039.runTaskExecutor(this.batchDoTasks, taskList)));
allResponse.forEach((result, index)=>{
this.updateResultMap(tasksGroup[index], result.status === "rejected" ? $d415641d0cfd8c85$export$2e2bcd8739ae039.wrapError(result.reason) : result.value);
});
this.checkAllTasks();
this.removeDoneTasks(tasks);
}
// remove all unresolved tasks
this.cleanupTasks();
}
/**
* 检查所有任务
* @param succeed 获取成功的结果对象
* @param failed 获取失败的 fileId 数组
*/ checkAllTasks(defaultResult) {
* check all tasks, try to resolve
*/ checkAllTasks() {
this.taskQueue.forEach((taskItem)=>{
try {
const result = this.tryGetTaskResult(taskItem.tasks, defaultResult);
const result = this.tryGetTaskResult(taskItem.tasks);
// eslint-disable-next-line no-param-reassign

@@ -161,12 +157,14 @@ taskItem.isDone = true;

}
tryGetTaskResult(tasks, defaultResult) {
/**
* get result list of given tasks
* throw error when not found(to make it easier to distinct from falsy results)
* @param tasks tasks to check
* @param defaultResult default result if not found
*/ tryGetTaskResult(tasks) {
// no cached data and no default result provided
if (!this.doneTaskMap.length && !defaultResult) throw new Error("no done task");
if (!this.doneTaskMap.length) throw new Error("no done task");
if (Array.isArray(tasks)) {
const result = [];
return tasks.reduce((acc, task)=>{
const val = this.getTaskResult(task) || (defaultResult ? [
task,
defaultResult
] : false);
const val = this.getTaskResult(task) || false;
if (!val) throw new Error("not found");

@@ -177,6 +175,3 @@ acc.push(val);

}
const val = this.getTaskResult(tasks) || (defaultResult ? [
tasks,
defaultResult
] : false);
const val = this.getTaskResult(tasks) || false;
if (!val) throw new Error("not found");

@@ -191,3 +186,2 @@ return val[1];

];
return undefined;
}

@@ -198,3 +192,3 @@ hasTask(list, task) {

removeDoneTasks(tasks) {
this.doingTasks = this.doingTasks.filter((f)=>this.hasTask(tasks, f));
this.doingTasks = this.doingTasks.filter((f)=>!this.hasTask(tasks, f));
}

@@ -224,20 +218,21 @@ updateResultMap(tasks, result) {

* clean tasks
* try to clean cache if needed
* try to remove failed result, remove outdated cache if needed
*/ cleanupTasks() {
// no doing tasks, but the que is not empty, aka, there is some unresolved tasks
if (this.taskQueue.length && !this.pendingTasks.length && !this.doingTasks.length) {
this.checkAllTasks(new Error("not found"));
this.taskQueue = [];
}
this.cleanCacheIfNeeded();
// has validity or retry flag and no taskQueue
if ((this.invalidAfter || this.retryWhenFailed) && !this.taskQueue.length) {
const now = Date.now();
this.doneTaskMap = this.doneTaskMap.filter((item)=>{
if (this.invalidAfter) return now - item.time <= this.invalidAfter;
if (this.retryWhenFailed) return !(item.value instanceof Error);
return true;
});
}
// has unresolved tasks, unable to cleanup task
if (this.taskQueue.length) return;
// no need to remove outdated or failed tasks
if (!this.invalidAfter && !this.retryWhenFailed) return;
const now = Date.now();
this.doneTaskMap = this.doneTaskMap.filter((item)=>{
if (this.retryWhenFailed && item.value instanceof Error) return false;
if (this.invalidAfter) return now - item.time <= this.invalidAfter;
return true;
});
}
static wrapError(e) {
/**
* wrap error info, if it's not instanceof Error, wrap it with Error
* @returns Error instance
*/ static wrapError(e) {
if (e instanceof Error) return e;

@@ -264,5 +259,5 @@ const newError = new Error("task failed");

* @returns
*/ static async wrapPromise(promise) {
*/ static async runTaskExecutor(executor, ...args) {
try {
const result = await promise;
const result = await executor(...args);
return {

@@ -275,6 +270,44 @@ status: "fulfilled",

status: "rejected",
reason: error
reason: $d415641d0cfd8c85$export$2e2bcd8739ae039.wrapError(error)
};
}
}
/**
* wrap do task to a batch version
* @param doTask action to do single task
* @returns batch version to do multi tasks
*/ static wrapDoTask(doTask) {
return async function(tasks) {
const results = await Promise.all(tasks.map((t)=>$d415641d0cfd8c85$export$2e2bcd8739ae039.runTaskExecutor(doTask, t)));
return tasks.map((t, idx)=>{
const result = results[idx];
return [
t,
result.status === "fulfilled" ? result.value : result.reason
];
});
};
}
/**
* check whether the given values are equal (with deep comparison)
*/ static isEqual(a, b) {
if (a === b) return true;
const typeA = typeof a;
const typeB = typeof b;
if (typeA !== typeB) return false;
// @ts-ignore
// for nan
if (typeA === "number" && isNaN(a) && isNaN(b)) return true;
// none object type, aka primitive types, are checked by the first line
if (typeA !== "object") return false;
// if one of them is regexp, check via regexp literal
if (a instanceof RegExp || b instanceof RegExp) return String(a) === String(b);
// only one is array
if (Array.isArray(a) !== Array.isArray(b)) return false;
// @ts-ignore
if (Object.keys(a).length !== Object.keys(b).length) return false;
// @ts-ignore
if (Object.keys(a).some((k)=>!$d415641d0cfd8c85$export$2e2bcd8739ae039.isEqual(a[k], b[k]))) return false;
return true;
}
}

@@ -281,0 +314,0 @@

@@ -16,5 +16,6 @@ function $parcel$defineInteropFlag(a) {

*/ static defaultOptions = {
isSameTask: (a, b)=>a === b,
isSameTask: $f5bfd4ce37214f4f$export$2e2bcd8739ae039.isEqual,
taskExecStrategy: "parallel",
maxWaitingGap: 50,
invalidAfter: 1000,
taskWaitingStrategy: "debounce",

@@ -35,6 +36,5 @@ retryWhenFailed: true

this.maxWaitingGap = userOptions.maxWaitingGap;
// @ts-ignore
this.taskWaitingStrategy = userOptions.taskWaitingStrategy;
this.batchDoTasks = userOptions.batchDoTasks;
// @ts-ignore
if (!userOptions.batchDoTasks && !userOptions.doTask) throw new Error("one of batchDoTasks / doTask must be specified");
this.batchDoTasks = userOptions.batchDoTasks || $f5bfd4ce37214f4f$export$2e2bcd8739ae039.wrapDoTask(userOptions.doTask);
this.taskExecStrategy = userOptions.taskExecStrategy;

@@ -49,4 +49,4 @@ this.retryWhenFailed = userOptions.retryWhenFailed;

const result = this.tryGetTaskResult(tasks);
if (result instanceof Error) throw result;
return result;
if (result instanceof Error) return Promise.reject(result);
return Promise.resolve(result);
} catch (error) {

@@ -88,5 +88,9 @@ // not found

];
// 去除掉正在等待的、正在处理的以及已经成功的
// remove duplicated tasks in itself
myTasks = myTasks.filter((task, idx)=>idx === myTasks.findIndex((t)=>this.isSameTask(t, task)));
// remove pending tasks
if (this.pendingTasks.length) myTasks = myTasks.filter((f)=>!this.hasTask(this.pendingTasks, f));
// remove doing tasks
if (myTasks.length && this.doingTasks.length) myTasks = myTasks.filter((f)=>!this.hasTask(this.doingTasks, f));
// remove done tasks
if (myTasks.length) myTasks = myTasks.filter((f)=>!this.getTaskResult(f));

@@ -107,9 +111,9 @@ if (!myTasks.length) return;

* if taskExecStrategy is parallel then do it immediately,
* otherwise waiting util taskQueue is empty
* otherwise waiting util doingTasks is empty
*/ tryTodDoTasks() {
// should exec in serial, and still has executing tasks
if (this.taskExecStrategy === "serial" && this.taskQueue.length) {
if (this.taskExecStrategy === "serial" && this.doingTasks.length) {
clearTimeout(this.delayTimeoutId);
// wait a moment then check again
this.delayTimeoutId = setTimeout(this.tryTodDoTasks, 100);
this.delayTimeoutId = setTimeout(this.tryTodDoTasks, 50);
} else this.doTasks();

@@ -137,25 +141,17 @@ }

else {
try {
const allResponse = await Promise.all(tasksGroup.map((taskList)=>$f5bfd4ce37214f4f$export$2e2bcd8739ae039.wrapPromise(this.batchDoTasks(taskList))));
allResponse.forEach((result, index)=>{
this.updateResultMap(tasksGroup[index], // @ts-ignore
result.status === "rejected" ? $f5bfd4ce37214f4f$export$2e2bcd8739ae039.wrapError(result.reason) : result.value);
});
} catch (error1) {
this.updateResultMap(tasks, $f5bfd4ce37214f4f$export$2e2bcd8739ae039.wrapError(error1));
}
const allResponse = await Promise.all(tasksGroup.map((taskList)=>$f5bfd4ce37214f4f$export$2e2bcd8739ae039.runTaskExecutor(this.batchDoTasks, taskList)));
allResponse.forEach((result, index)=>{
this.updateResultMap(tasksGroup[index], result.status === "rejected" ? $f5bfd4ce37214f4f$export$2e2bcd8739ae039.wrapError(result.reason) : result.value);
});
this.checkAllTasks();
this.removeDoneTasks(tasks);
}
// remove all unresolved tasks
this.cleanupTasks();
}
/**
* 检查所有任务
* @param succeed 获取成功的结果对象
* @param failed 获取失败的 fileId 数组
*/ checkAllTasks(defaultResult) {
* check all tasks, try to resolve
*/ checkAllTasks() {
this.taskQueue.forEach((taskItem)=>{
try {
const result = this.tryGetTaskResult(taskItem.tasks, defaultResult);
const result = this.tryGetTaskResult(taskItem.tasks);
// eslint-disable-next-line no-param-reassign

@@ -172,12 +168,14 @@ taskItem.isDone = true;

}
tryGetTaskResult(tasks, defaultResult) {
/**
* get result list of given tasks
* throw error when not found(to make it easier to distinct from falsy results)
* @param tasks tasks to check
* @param defaultResult default result if not found
*/ tryGetTaskResult(tasks) {
// no cached data and no default result provided
if (!this.doneTaskMap.length && !defaultResult) throw new Error("no done task");
if (!this.doneTaskMap.length) throw new Error("no done task");
if (Array.isArray(tasks)) {
const result = [];
return tasks.reduce((acc, task)=>{
const val = this.getTaskResult(task) || (defaultResult ? [
task,
defaultResult
] : false);
const val = this.getTaskResult(task) || false;
if (!val) throw new Error("not found");

@@ -188,6 +186,3 @@ acc.push(val);

}
const val = this.getTaskResult(tasks) || (defaultResult ? [
tasks,
defaultResult
] : false);
const val = this.getTaskResult(tasks) || false;
if (!val) throw new Error("not found");

@@ -202,3 +197,2 @@ return val[1];

];
return undefined;
}

@@ -209,3 +203,3 @@ hasTask(list, task) {

removeDoneTasks(tasks) {
this.doingTasks = this.doingTasks.filter((f)=>this.hasTask(tasks, f));
this.doingTasks = this.doingTasks.filter((f)=>!this.hasTask(tasks, f));
}

@@ -235,20 +229,21 @@ updateResultMap(tasks, result) {

* clean tasks
* try to clean cache if needed
* try to remove failed result, remove outdated cache if needed
*/ cleanupTasks() {
// no doing tasks, but the que is not empty, aka, there is some unresolved tasks
if (this.taskQueue.length && !this.pendingTasks.length && !this.doingTasks.length) {
this.checkAllTasks(new Error("not found"));
this.taskQueue = [];
}
this.cleanCacheIfNeeded();
// has validity or retry flag and no taskQueue
if ((this.invalidAfter || this.retryWhenFailed) && !this.taskQueue.length) {
const now = Date.now();
this.doneTaskMap = this.doneTaskMap.filter((item)=>{
if (this.invalidAfter) return now - item.time <= this.invalidAfter;
if (this.retryWhenFailed) return !(item.value instanceof Error);
return true;
});
}
// has unresolved tasks, unable to cleanup task
if (this.taskQueue.length) return;
// no need to remove outdated or failed tasks
if (!this.invalidAfter && !this.retryWhenFailed) return;
const now = Date.now();
this.doneTaskMap = this.doneTaskMap.filter((item)=>{
if (this.retryWhenFailed && item.value instanceof Error) return false;
if (this.invalidAfter) return now - item.time <= this.invalidAfter;
return true;
});
}
static wrapError(e) {
/**
* wrap error info, if it's not instanceof Error, wrap it with Error
* @returns Error instance
*/ static wrapError(e) {
if (e instanceof Error) return e;

@@ -275,5 +270,5 @@ const newError = new Error("task failed");

* @returns
*/ static async wrapPromise(promise) {
*/ static async runTaskExecutor(executor, ...args) {
try {
const result = await promise;
const result = await executor(...args);
return {

@@ -286,8 +281,46 @@ status: "fulfilled",

status: "rejected",
reason: error
reason: $f5bfd4ce37214f4f$export$2e2bcd8739ae039.wrapError(error)
};
}
}
/**
* wrap do task to a batch version
* @param doTask action to do single task
* @returns batch version to do multi tasks
*/ static wrapDoTask(doTask) {
return async function(tasks) {
const results = await Promise.all(tasks.map((t)=>$f5bfd4ce37214f4f$export$2e2bcd8739ae039.runTaskExecutor(doTask, t)));
return tasks.map((t, idx)=>{
const result = results[idx];
return [
t,
result.status === "fulfilled" ? result.value : result.reason
];
});
};
}
/**
* check whether the given values are equal (with deep comparison)
*/ static isEqual(a, b) {
if (a === b) return true;
const typeA = typeof a;
const typeB = typeof b;
if (typeA !== typeB) return false;
// @ts-ignore
// for nan
if (typeA === "number" && isNaN(a) && isNaN(b)) return true;
// none object type, aka primitive types, are checked by the first line
if (typeA !== "object") return false;
// if one of them is regexp, check via regexp literal
if (a instanceof RegExp || b instanceof RegExp) return String(a) === String(b);
// only one is array
if (Array.isArray(a) !== Array.isArray(b)) return false;
// @ts-ignore
if (Object.keys(a).length !== Object.keys(b).length) return false;
// @ts-ignore
if (Object.keys(a).some((k)=>!$f5bfd4ce37214f4f$export$2e2bcd8739ae039.isEqual(a[k], b[k]))) return false;
return true;
}
}

@@ -0,13 +1,61 @@

export type ITaskExecStrategy = 'parallel' | 'serial';
export type ITaskWaitingStrategy = 'throttle' | 'debounce';
export default class AsyncTask<Task, Result> {
constructor(options: {
/**
* max batch tasks count when dispatching
*/
maxBatchCount?: number;
batchDoTasks: (tasks: Task[]) => Promise<Array<[Task, Result | Error]>>;
taskExecStrategy?: 'parallel' | 'serial';
/**
* action to do batch tasks
* one of batchDoTasks/doTask must be specified, batchDoTasks will take priority
*/
batchDoTasks?: (tasks: Task[]) => Promise<Array<[Task, Result | Error]>> | Array<[Task, Result | Error]>;
/**
* action to do single task
* one of batchDoTasks/doTask must be specified, batchDoTasks will take priority
*/
doTask?: (task: Task) => Promise<Result> | Result;
/**
* do batch tasks executing strategy, default to parallel
*/
taskExecStrategy?: ITaskExecStrategy;
/**
* max waiting time(in milliseconds) for combined tasks, default to 50
*/
maxWaitingGap?: number;
/**
* task result caching duration(in milliseconds), default to 1s
* >`undefined` or `0` for unlimited
* >set to minimum value `1` to disable caching
*
* *cache is lazy cleaned after invalid*
*/
invalidAfter?: number;
/**
* retry failed tasks next time after failing, default true
*/
retryWhenFailed?: boolean;
/**
* task waiting stragy, default to debounce
* throttle: tasks will combined and dispatch every `maxWaitingGap`
* debounce: tasks will combined and dispatch util no more tasks in next `maxWaitingGap`
*/
taskWaitingStrategy?: ITaskWaitingStrategy;
/**
* check whether two tasks are identified the same
*/
isSameTask?: (a: Task, b: Task) => boolean;
});
/**
* execute task, get task result in promise
*/
dispatch(task: Task): Promise<Result>;
dispatch(tasks: Task[]): Promise<[[Task, Result | Error]]>;
/**
* execute tasks, get response in tuple of task and result/error
*/
dispatch<T extends readonly Task[] | []>(tasks: T): Promise<{
[k in keyof T]: [Task, Result | Error];
}>;
/**
* clean cached task result

@@ -17,4 +65,8 @@ * this may not exec immediately, it will take effect after all tasks are done

cleanCache(): void;
static wrapError(e: any): Error;
/**
* wrap error info, if it's not instanceof Error, wrap it with Error
* @returns Error instance
*/
static wrapError(e: unknown): Error;
/**
* split array to chunks with specified size

@@ -32,11 +84,19 @@ * @param arr array of fileIds

*/
static wrapPromise<T>(promise: Promise<T>): Promise<{
status: string;
value: Awaited<T>;
reason?: undefined;
static runTaskExecutor<A extends Array<unknown>, F extends ((...args: A) => unknown)>(executor: F, ...args: A): Promise<{
status: 'fulfilled';
value: Awaited<ReturnType<F>>;
} | {
status: string;
reason: unknown;
value?: undefined;
status: 'rejected';
reason: Error;
}>;
/**
* wrap do task to a batch version
* @param doTask action to do single task
* @returns batch version to do multi tasks
*/
static wrapDoTask<T, R>(doTask: (t: T) => Promise<R> | R): (tasks: T[]) => Promise<Array<[T, R | Error]>>;
/**
* check whether the given values are equal (with deep comparison)
*/
static isEqual(a: unknown, b: unknown): boolean;
}
{
"name": "async-task-schedule",
"version": "0.0.2",
"version": "0.0.3",
"description": "schedule async tasks",

@@ -12,4 +12,4 @@ "main": "dist/index.js",

"clean": "rimraf dist",
"test": "jest",
"prepublish": "yarn test && yarn build"
"test": "jest --coverage",
"release": "yarn test && yarn build && yarn publish"
},

@@ -16,0 +16,0 @@ "keywords": [

@@ -24,3 +24,3 @@ # async-task-schedule

* combine tasks' requests in same time and do all together
* can prevent massive requests at same time, make them executing one group by one group
* can prevent massive requests at same time, make them execute one group by one group
* cache result and can specify validity

@@ -76,6 +76,12 @@

*
* batchDoTasks should receive multi tasks, and return tuple of task and response or error in array
* batchDoTasks should receive multitasks, and return tuple of task and response or error in array
* one of batchDoTasks/doTask must be specified, batchDoTasks will take priority
*/
private batchDoTasks: (tasks: Task[]) => Promise<Array<[Task, Result | Error ]>>
/**
* action to do single task
* one of batchDoTasks/doTask must be specified, batchDoTasks will take priority
*/
doTask?: ((task: Task) => Promise<Result>)

@@ -96,3 +102,3 @@ /**

/**
* do batch tasks executing strategy, default parallel
* batch tasks executing strategy, default parallel
* only works if maxBatchCount is specified and tasks more than maxBatchCount are executed

@@ -103,3 +109,3 @@ *

* if serial specified, when tasks are executing, new comings will wait for them to complete
* it's very useful to cool down task requests
* it's especially useful to cool down task requests
*/

@@ -124,2 +130,3 @@ private taskExecStrategy: 'parallel' | 'serial'

* undefined or 0 for unlimited
* cache is lazy cleaned after invalid
*/

@@ -136,5 +143,5 @@ private invalidAfter?: number

### dispatch(tasks: Task[]):Promise<Array<[Task, Result | Error]>>
dispatch multi tasks at a time, will get tuple of task and response in array
dispatch multitasks at a time, will get tuple of task and response in array
this method won't throw any error, it will fulfilled even partially failed, you can check whether its success by `tuple[1] instanceof Error`
this method won't throw any error, it will fulfil even partially failed, you can check whether its success by `tuple[1] instanceof Error`

@@ -155,3 +162,3 @@ ### dispatch(tasks: Task):Promise<Result>

#### example 1
suppose we have a method `getUsers` defined as follow:
suppose we have a method `getUsers` defined as follows:

@@ -187,5 +194,5 @@ ```ts

#### example 2
if the request parameter is a object, then we should provide a `isSameTask` to identify unique task
if the request parameter is an object, then we should provide a `isSameTask` to identify unique task
suppose we have a method `decodeGeoPoints` defined as follow:
suppose we have a method `decodeGeoPoints` defined as follows:

@@ -196,3 +203,4 @@ ```ts

then we can integrate as follow
then we can integrate as follows:
```ts

@@ -217,3 +225,3 @@ async function batchDecodeGeoPoints(points: Array<{lat: number, long: number}>): Promise<Array<[{lat: number, long: number}, {point: {lat: number, long: number}, title: string, description: string, country: string}]>> {

// request combine won't works when using await
// request combine won't work when using await
const result1 = await decodePointsAsyncTask.dispatch([{lat: 23.232, long: 43.121}, {lat: 33.232, long: 11.1023}])

@@ -224,3 +232,3 @@ const result2 = await decodePointsAsyncTask.dispatch([{lat: 23.232, long: 43.121}, {lat: 33.232, long: 44.2478}]).then(console.log)

### how to cool down massive requests at same time
### how to cool down massive requests at the same time
by setting `taskExecStrategy` to `serial` and using smaller `maxBatchCount`(you can even set it to `1`), you can achieve this easily

@@ -227,0 +235,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc