@haravan-tech/util
Version:
utilities
135 lines (123 loc) • 3.52 kB
JavaScript
;
/**
* @namespace lang
* @memberof util
*/
module.exports = {
to : to,
toMap : toMap,
toResolve : toResolve,
setTimeoutPromise : setTimeoutPromise,
PromiseAllStep : PromiseAllStep
};
/**
* change the way handle promise
* @memberof util.lang
* @param {Object} promise
* @return {any[]} [error, result]
* @example
```js
// To handle mongoose error, instead of try catch :
try {
let store = await StoresModel.findOne({ id : 1000 });
}
catch (err) {
// handle mongoose error
}
// You can :
let [err, store] = await to(StoresModel.findOne({ id : 1000 }));
if (err) {
// handle mongoose error
}
```
*/
function to(promise) {
return promise.then(data => {
return [null, data]
})
.catch(err => [err]);
}
/**
* Wrap a callback-based-API with a promise that only resolve all callback arguments,
* and doesn't reject anything
* @memberof util.lang
* @param {function} callbackBasedAPI - The function that you want to wrap
* @return {promise} Promisified API
* @example
```js
// assume you have an function
function callbackBasedAPI(a1, a2, ..., aN, callback) {
// do something ...
callback(err, res1, res2, ..., resN);
}
// and want to receive all callback argument in one call through async/await, like :
let [err, res1, res2, ..., resN] = await callbackBasedAPI(a1, a2, ..., aN);
// so can easily handle error :
if (err) {
handleError(err);
}
// just wrap it with before use
let callbackBasedAPI = toResolve(callbackBasedAPI);
```
*/
function toResolve(callbackBasedAPI) {
return function(...f_args) {
let $this = this;
return new Promise((resolve) => {
function callback(...args) {
return resolve(args);
}
f_args.push(callback);
callbackBasedAPI.apply($this, f_args);
});
}
}
function toMap(arr, key) {
let res = new Map();
if (Array.isArray(arr)) {
arr.forEach(elem => {
res.set(elem[key], elem);
});
}
return res;
}
function setTimeoutPromise(callback, timeout, thisArg, ...args) {
return new Promise((resolve, reject) => {
setTimeout(() => {
let result = undefined;
if (typeof callback === 'function') {
try {
result = callback.apply(thisArg, args);
}
catch (err) {
return reject(err);
}
}
return resolve(result);
}, timeout);
});
}
/**
* Applies the function iteratee to each item in coll after timeout, which's increased by step
* @memberof util.lang
* @param {array} coll A collection to iterate over
* @param {function} iteratee An async function to apply to each item in coll. Apply with (thisArg, item, index)
* @param {number} step Amount of milisecond that timeout increase after each item
* @param {object} thisArg The this pointer of iteratee
* @return {promise} like Promise.all result
*
* @example
```js
await PromiseAllStep(['hello', 'world', 'from', 'Vietnam !'], async word => console.log(word), 200);
Will print :
hello // after 0ms
world // after 200ms
from // after 400ms
Vietnam // after 600ms
```
*/
function PromiseAllStep(coll, iteratee, step, thisArg) {
return Promise.all(coll.map((item, index) => {
return setTimeoutPromise(iteratee, step * index, thisArg, item, index);
}, thisArg));
}