const isOfType = (() => { // create a plain object with no prototype const type = Object.create(null); // check for null type type.null = x => x === null; // check for undefined type type.undefined = x => x === undefined; // check for nil type. Either null or undefined type.nil = x => type.null(x) || type.undefined(x); // check for strings and string literal type. e.g: 's', "s", `str`, new String() type.string = x => !type.nil(x) && (typeof x === 'string' || x instanceofString); // check for number or number literal type. e.g: 12, 30.5, new Number() type.number = x => !type.nil(x) && (// NaN & Infinity have typeof "number" and this excludes that (!isNaN(x) && isFinite(x) && typeof x === 'number' ) || x instanceofNumber); // check for boolean or boolean literal type. e.g: true, false, new Boolean() type.boolean = x => !type.nil(x) && (typeof x === 'boolean' || x instanceofBoolean); // check for array type type.array = x => !type.nil(x) && Array.isArray(x); // check for object or object literal type. e.g: {}, new Object(), Object.create(null) type.object = x => ({}).toString.call(x) === '[object Object]'; // check for provided type instance type.type = (x, X) => !type.nil(x) && x instanceof X; // check for set type type.set = x => type.type(x, Set); // check for map type type.map = x => type.type(x, Map); // check for date type type.date = x => type.type(x, Date); return type; })();
2. 检查是否为空
有时你需要知道某些内容是否为空,并根据结果决定要使用的方法,例如检查长度、大小或是否包含任何子元素。下面这个工具打包了这些功能,你可以用它检查 String、Object、Array、Map 和 Set 的大小。
有时你只是需要一些 ID?除非你要的是更复杂的 ID 生成器(例如 UUID),否则用不着为此安装什么新库,下面这个选项足够了。你可以从当前时间(以毫秒为单位)或特定的整数和增量开始生成,也可以从字母生成 ID。
// create unique id starting from current time in milliseconds // incrementing it by 1 everytime requested const uniqueId = (() => { const id = (function*() { let mil = newDate().getTime(); while (true) yield mil += 1; })(); return() => id.next().value; })(); // create unique incrementing id starting from provided value or zero // good for temporary things or things that id resets const uniqueIncrementingId = ((lastId = 0) => { const id = (function*() { let numb = lastId; while (true) yield numb += 1; })() return(length = 12) =>`${id.next().value}`.padStart(length, '0'); })(); // create unique id from letters and numbers const uniqueAlphaNumericId = (() => { const heyStack = '0123456789abcdefghijklmnopqrstuvwxyz'; const randomInt = () =>Math.floor(Math.random() * Math.floor(heyStack.length)) return(length = 24) =>Array.from({length}, () => heyStack[randomInt()]).join(''); })();
6. 创建一个范围内的数字
Python 里我很喜欢的一个功能是 range 函数,而在 JavaScript 里我经常需要自己写这个功能。下面是一个简单的实现,非常适合 for…of 循环以及需要特定范围内数字的情况。
const asyncSequentializer = (() => { const toPromise = (x) => { if(x instanceofPromise) { // if promise just return it return x; } if(typeof x === 'function') { // if function is not async this will turn its result into a promise // if it is async this will await for the result return (async () => await x())(); } returnPromise.resolve(x) } return(list) => { const results = []; return list .reduce((lastPromise, currentPromise) => { return lastPromise.then(res => { results.push(res); // collect the results return toPromise(currentPromise); }); }, toPromise(list.shift())) // collect the final result and return the array of results as resolved promise .then(res =>Promise.resolve([...results, res])); } })();
asyncfunctionpoll(fn, validate, interval = 2500) { const resolver = async (resolve, reject) => { try { // catch any error thrown by the "fn" function const result = await fn(); // fn does not need to be asynchronous or return promise // call validator to see if the data is at the state to stop the polling const valid = validate(result); if (valid === true) { resolve(result); } elseif (valid === false) { setTimeout(resolver, interval, resolve, reject); } // if validator returns anything other than "true" or "false" it stops polling } catch (e) { reject(e); } }; returnnewPromise(resolver); }
10. 等待所有 promise 完成
这个算不上是代码解决方案,更多是对 Promise API 的强化。这个 API 在不断进化,以前我还为“allSettled”“race”和“any”做了代码实现,现在直接用 API 的就好了。