PromiseHelper
serialEach
Serially (not in parallel) calls a processing function on each element of an array waiting for each to resolve before processing the next item.
If any invocation of process throws an error or returns a rejected promise, serialEach halts processing and returns a rejected promise. Otherwise, serialEach returns a promise resolved with void.
Hsl.PromiseHelper.serialEach<T>(inputArray: T[], process: (value: T, ix: number) => Promise<any>): Promise<void>;
inArray: T[]
An array of values to mapprocess: (value: T, ix: number) => Promise<any>
Function applied to each element which is expected to return a promise which resolves with anything. The promise will be waited on before moving to the next input element. Two arguments are passed to process:- The element to process
- The index of the element in the input array.
function updateSerially(contactIds) {
const client = Hsl.WebApi.getClient('9.0');
Hsl.PromiseHelper.serialEach(contactIds, id => {
return client.update({ id, entityType: 'contact' }, {
creditonhold: false,
});
});
}
serialMap
Serially (not in parallel) maps each value from an input array using the process function. (Similar to [].map except serially waiting for each promise to resolve.)
Hsl.PromiseHelper.serialMap<T, TResult>(inputArray: T[], process: (value: T, ix: number) => Promise<TResult>): Promise<TResult[]>;
inArray: T[]
An array of values to mapprocess: (value: T, ix: number) => Promise<TResult>
Function applied to each element which is expected to return a promise which resolves with the result value.- The element to process
- The index of the element in the input array.
function parallelRecordCreation() {
const client = Hsl.WebApi.getClient('9.0');
const srcData = getSourceData(20);
return Promise.all(srcData.map(data => {
return client.create('account', {
name: data,
});
}));
function getSourceData(count) {
const r = new Date().toISOString();
return Array(count).map((x, ix) => {
return r + ' Account ' + ix;
});
}
}
function createRecordsSerially(context) {
const client = Hsl.WebApi.getClient('9.0');
const form = Hsl.form(context);
const parent = form.getReference();
Hsl.Dialog.lookup({
target: 'product'
}).then(result => {
if (result.cancelled)
return;
const busyDlg = Hsl.Dialog.openBusy({ progress: 0, text: 'Processing...' });
Hsl.PromiseHelper.serialMap(result.records, productRef => {
// Create a product detail record for each item selected in the dialog.
return client.create('hsl_productdetail', {
hsl_name: productRef.name,
hsl_productid: Hsl.WebApi.bindReference(productRef),
hsl_parentid: Hsl.WebApi.bindReference(parent),
}).then(detailId => {
return {
detailId,
productRef,
};
});
}).then(detailIds => {
// Create links to the created records.
const links = detailIds
.map(x => `<a href="${Hsl.xmlEncode(Hsl.prependOrgName('/main.aspx?pagetype=entityrecord&etn=hsl_productdetail&id=' + x.detailId))}">${Hsl.xmlEncode(x.productRef.name || '(Unnamed)')}</a>`);
Hsl.Dialog.open({
contentHtml: links.join('<br>'),
buttons: [{
label: 'Ok',
action(ctx) {
ctx.close();
},
width: '3em',
}]
});
}).catch(Hsl.Dialog.showError).then(() => busyDlg.close());
});
}
throttledParallelMap
Processes data in parallel mapping each value in the input array using the process function. The concurrencyFactor parameter sets the maximum number of items processing at any given time.
Hsl.PromiseHelper.throttledParallelEach<TInput>(inputArray: TInput[], concurrencyFactor: number, process: (value: TInput, ix: number) => Promise<any>): Promise<void>;
inArray: T[]
An array of values to mapconcurrencyFactor: number
The maximum number of items processing at any given time.process: (value: TInput, ix: number) => Promise<any>
Function applied to each element which is expected to return a promise. The promise will be waited on before moving to the next input element based on the concurrencyFactor.
// For larger datasets, fully parallel record creation might cause timouts or other issues.
// This sample will have at most 20 outgoing requests at a time.
function throttledParallelRecordCreation() {
const client = Hsl.WebApi.getClient('9.0');
const ConcurrencyFactor = 20;
let countCompleted = 0;
const srcData = getSourceData(5000);
const dlg = Hsl.Dialog.openBusy({
text: 'Processing records...',
});
return Hsl.PromiseHelper.throttledParallelMap(srcData, ConcurrencyFactor, data => {
return client.create('account', {
name: data,
}).then(accountId => {
countCompleted += 1;
dlg.update({
progress: countCompleted / srcData.length,
});
return accountId;
});
}).then(accountIds => {
Hsl.Dialog.alert(`Created ${srcData.length} accounts with ids:\r\n${accountIds.join('\r\n')}`);
});
function getSourceData(count) {
const r = new Date().toISOString();
return Array(count).map((x, ix) => {
return r + ' Account ' + ix;
});
}
}
throttledParallelEach
Processes data in parallel for each value in the input array using the process function. The concurrencyFactor parameter sets the maximum number of items processing at any given time.
Hsl.PromiseHelper.throttledParallelMap<TInput, TResult>(inputArray: TInput[], concurrencyFactor: number, process: (value: TInput, ix: number) => Promise<TResult>): Promise<TResult[]>;
inArray: T[]
An array of values to mapconcurrencyFactor: number
The maximum number of items processing at any given time.process: (value: TInput, ix: number) => Promise<TResult>
Function applied to each element which is expected to return a promise which resolves with the mapped value that should be placed into the final array. The promise will be waited on before moving to the next input element based on the concurrencyFactor.