Appearance
全局配置
Appearance
有一个数组:
const arr = [[1,2],3,[4,5,6]];
定义一个函数,传入arr后,返回值为一个二维数组:
[[1,3,4],[2,3,4],[1,3,5],[2,3,5],[1,3,6],[2,3,6]]
function f(arr) {
// 用于存放最后结果的空数组
var ret = []
// 函数result
function fi(result, i) {
if (i === -1) {
ret.push(result)
} else {
let items = arr[i]
if (!Array.isArray(items)) {
items = [items]
}
items.forEach(item => {
fi([item,...result], i - 1)
});
}
}
fi([], arr.length - 1)
return ret
}
const arr = [[1,2],3,[4,5,6]];
console.log(f(arr))
function _toConsumableArray(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
arr2[i] = arr[i];
}
return arr2;
} else {
return Array.from(arr);
}
}
function f(arr) {
var ret = [];
function fi(result, i) {
if (i === -1) {
ret.push(result);
} else {
var items = arr[i];
if (!Array.isArray(items)) {
items = [items];
}
items.forEach(function (item) {
fi([item].concat(_toConsumableArray(result)), i - 1);
});
}
}
fi([], arr.length - 1);
return ret;
}
var arr = [[1, 2], 3, [4, 5, 6]];
console.log(f(arr));
如何提取数组中的字段,然后添加新的字段,获取数据如下:
var data = [
{"id":"1","name":"华为","data":"25u6s8f545d3"},
{"id":"2","name":"小米","data":"cd58de9d3c5d"},
];
想获得的数据格式如下:
var data = [
{"id":"1","name":"华为","data":"25u6s8f545d3","mac":"25:u6:s8:f5:45:d3"},
{"id":"2","name":"小米","data":"cd58de9d3c5d","mac":"cd:58:de:9d:3c:5d"},
];
var data = [
{ "id": "1", "name": "华为", "data": "25u6s8f545d3" },
{ "id": "2", "name": "小米", "data": "cd58de9d3c5d" },
];
data.forEach(item => {
item.mac = item.data.replace(/\w{2}\B/g, '$&:')
})
console.log(data)
打印类似效果:
4444
333
22
1
22
333
4444
function f(n) {
for (let i = -n; i <= n; i++) {
if (i === 0 || i === 1) {
continue
}
let k = Math.abs(i)
console.log(k.toString().repeat(k))
}
}
f(4);
让字符串"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 每7个字符换行一次
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aa
var str='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
var result = str.replace(/(.{7})/g, '$1\n')
console.log(result);
请写一段js程序,定义一个列表类List,该类包括两个成员:属性length(表示列表中的元素个数)和方法add(向列表添加元素),其中要求构造函数和add方法的参数为动态参数。
class List{
constructor(...items){
this.items = items
this.length = items.length
}
add(...items) {
this.items.push(...items)
this.length = this.items.length
}
}
比如有这样一个对象数组:
let data = [
{
title: '标题一',
tagName: 'h1'
},
{
title: '标题二',
tagName: 'h1'
},
{
title: '标题三',
tagName: 'h2'
},
{
title: '标题四',
tagName: 'h3'
},
{
title: '标题五',
tagName: 'h2'
},
{
title: '标题六',
tagName: 'h1'
},
{
title: '标题七',
tagName: 'h1'
},
{
title: '标题八',
tagName: 'h2'
},
{
title: '标题九',
tagName: 'h3'
},
{
title: '标题十',
tagName: 'h3'
}
]
要求根据tagName的优先级,从h1开始排,一直到h6,每个h1后面直到下个h1之前的都是它的children节点,依此类推,比如上面的数据这样处理后就会像下面的格式:
let data = [
{
title: '标题一',
tagName: 'h1'
},
{
title: '标题二',
tagName: 'h1',
children: [
{
title: '标题三',
tagName: 'h2'
children: [
{
title: '标题四',
tagName: 'h3'
}
]
},
{
title: '标题五',
tagName: 'h2'
}
]
},
{
title: '标题六',
tagName: 'h1'
},
{
title: '标题七',
tagName: 'h1',
children: [
{
title: '标题八',
tagName: 'h2',
children: [
{
title: '标题九',
tagName: 'h3'
},
{
title: '标题十',
tagName: 'h3'
}
]
}
]
}
]
function collect(arr, i, parent) {
if (i >= arr.length) {
return i
}
let current = arr[i]
if (current.tagName > parent.tagName) {
parent.children.push(current)
} else {
return i
}
i++
let next = arr[i]
if (!next) {
return i
}
if (next.tagName > current.tagName) {
current.children = []
i = collect(arr, i, current)
}
return collect(arr, i, parent)
}
var ret = {
tagName: 'h0',
children: []
}
collect(data, 0, ret)
console.log(ret.children)
使用random函数每次随机分配。每次得出的红包值大于 [0.01],小于 [剩余金额-剩余人数*0.01],最后一个人获得剩余全部。
function rp(total, n) {
var remain = total
var ret = []
for (let i = 0; i < n - 1;i++) {
let m = Math.ceil(Math.random() * 100 * (remain - (n - (i + 1)) * 0.01)) / 100
ret.push(m)
remain -= m
}
ret.push(Number(remain.toFixed(2)))
return ret
}
简化下面的函数:
function mergeJsonObject(jsonObj1, jsonObj2, jsonObj3, jsonObj4, jsonObj5) {
let resultJsonObject = {};
function jsonObj(jsonObj) {
for (let attr in jsonObj) {
resultJsonObject[attr] = jsonObj[attr];
}
}
jsonObj(jsonObj1);
jsonObj(jsonObj2);
jsonObj(jsonObj3);
jsonObj(jsonObj4);
jsonObj(jsonObj5);
return resultJsonObject;
}
function mergeJsonObject(...args) {
let resultJsonObject = {};
function jsonObj(jsonObj) {
for (let attr in jsonObj) {
resultJsonObject[attr] = jsonObj[attr];
}
}
args.forEach(jsonObj)
return resultJsonObject;
}
一段字符串如下:
表名1@字段1~表名1@字段2~表名2@字段1~表名2@字段2
如何将其合理地处理为json格式,如:
{
表名1:[字段1,字段2],
表名2:[字段1, 字段2]
}
var str = '表名1@字段1~表名1@字段2~表名2@字段1~表名2@字段2'
var obj = str.split('~').reduce((state, item) => {
var [tname, fname] = item.split('@')
if (state[tname]) {
state[tname].push(fname)
} else {
state[tname] = [fname]
}
return state
}, {})
某个对象:
var prd = {
"id": 1,
"department_id": 42,
"products": [{
"id": 12,
"name": "49da",
"grouped_addons": [{
"addons": [{
"id": "0_0_40",
"name": "rice",
"qty": 0,
"unit_price": "5.00"
},
{
"id": "0_0_41",
"name": "what",
"qty": 1,
"unit_price": "15.00"
}
]
}]
},
{
"id": 12,
"name": "49da",
"grouped_addons": [{
"addons": [{
"id": "0_0_40",
"name": "rice",
"qty": 0,
"unit_price": "5.00"
}, {
"id": "0_0_41",
"name": "what",
"qty": 1,
"unit_price": "15.00"
}]
}]
},
{
"id": 42,
"name": "345dd",
"grouped_addons": [{
"addons": [{
"id": "0_0_42",
"name": "rice",
"qty": 0,
"unit_price": "5.00"
}, {
"id": "0_0_43",
"name": "what",
"qty": 1,
"unit_price": "15.00"
}]
}]
},
{
"id": 48,
"name": "33ffg",
"grouped_addons": [{
"addons": [{
"id": "0_0_44",
"name": "rice",
"qty": 0,
"unit_price": "5.00"
}, {
"id": "0_0_45",
"name": "what",
"qty": 1,
"unit_price": "15.00"
}]
}]
},
{
"id": 48,
"name": "33ffg",
"grouped_addons": [{
"addons": [{
"id": "0_0_44",
"name": "rice",
"qty": 1,
"unit_price": "5.00"
}, {
"id": "0_0_45",
"name": "what",
"qty": 3,
"unit_price": "15.00"
}]
}]
}
]
}
想要将prd中的products中id相同的对象中的grouped_addons内id相同的qty相加合并,最终的结果想要如下:
var prd = {
"id": 1,
"department_id": 42,
"products": [{
"id": 12,
"name": "49da",
"grouped_addons": [{
"addons": [{
"id": "0_0_40",
"name": "rice",
"qty": 0,
"unit_price": "5.00"
},
{
"id": "0_0_41",
"name": "what",
"qty": 2,
"unit_price": "15.00"
}
]
}]
},
{
"id": 42,
"name": "345dd",
"grouped_addons": [{
"addons": [{
"id": "0_0_42",
"name": "rice",
"qty": 0,
"unit_price": "5.00"
}, {
"id": "0_0_43",
"name": "what",
"qty": 1,
"unit_price": "15.00"
}]
}]
},
{
"id": 48,
"name": "33ffg",
"grouped_addons": [{
"addons": [{
"id": "0_0_44",
"name": "rice",
"qty": 1,
"unit_price": "5.00"
}, {
"id": "0_0_45",
"name": "what",
"qty": 4,
"unit_price": "15.00"
}]
}]
}
]
}
var mp = prd.products.reduce((obj, item) => {
if (!obj[item.id]) {
obj[item.id] = [item]
} else {
obj[item.id].push(item)
}
return obj
}, {})
prd.products = Object.keys(mp).map(id => {
return mp[id].reduce((state, item) => {
item.grouped_addons[0].addons.forEach(addon => {
var item = state.grouped_addons[0].addons.find(a => a.id === addon.id)
item.qty += addon.qty
})
return state
})
})
console.log(prd)
写一个叫做 laugh() 的函数,它有一个参数n,表示要返回的 "ha" 的数量。
// ES6
function laugh (n) {
// ES6中`repeat`方法返回一个新字符串,表示将原字符串重复`n`次。参数如果是小数,会被取整。
return 'ha'.repeat(n)
}
// ES5
function laugh (n) {
var result = ''
for (var i = 0; i < n; i++) {
result += 'ha'
}
return result
}
从数字 1 循环访问到 20
如果数字可以被 3 整除,则输出 “Julia”
如果可以被 5 整除,则输出 “James”
如果可以同时被 3 和 5 整除,则输出 “JuliaJames”
如果不能被 3 或 5 整除,则输出该数字
for (var i = 1; i < 21; i++) {
(function (n) {
test(n);
})(i)
}
function test(num) {
if ((num % 3 === 0) && (num % 5 === 0)) {
console.log("JuliaJames");
}
if (num % 3 === 0) {
console.log("Julia");
}
if(num % 5 === 0) {
console.log("James");
}
console.log(num);
假设现在有两个函数function A()和function B(),现在希望创建一个新的函数function C(),新函数的逻辑是将自己接收到的前两个参数传给函数A,剩余所有参数传给函数B,请用原生javascript实现函数C
举例:
如果调用函数C:C(a,b,c,d,e)
相当于调用函数A和函数B:A(a,b)和B(c,d,e)
// ES5
function C() {
var args = [].slice.call(arguments)
A.apply(null, args.slice(0, 2))
B.apply(null, args.slice(2))
}
// ES6 展开运算符
function a(v1, v2){
console.log(v1, v2);
}
function b(...v){
console.log(v);
}
function c(...all){
a(all[0], all[1]);
b(...(all.slice(2)));
}
c(1, 2, 3, 4, 5, 6, 7);
已知函数 fn 执行需要 3 个参数。请实现函数 partial,调用之后满足如下条件:
1、返回一个函数 result,该函数接受一个参数
2、执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致
function partial(fn,str1,str2) {
var result = function(str3) {
return fn.call(null,str1,str2,str3);
}
return result;
}
给定一种 pattern(模式) 和一个字符串 str ,判断 str 是否遵循相同的模式。
这里的遵循指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应模式。
示例1:
输入: pattern = "abba", str = "dog cat cat dog"
输出: true
示例2:
输入:pattern = "abba", str = "dog cat cat fish"
输出: false
说明:
你可以假设 pattern 只包含小写字母, str 包含了由单个空格分隔的小写字母。
思路:
用JS ES6的Map结构,将pattern和str作为键值对传入数组,如果Map中存在pattern中的键,则比较Str中值;如果不存在键,则看Str中的值在Map中是否存在。如果键和值都在Map中,则将键值对加入Map中
var wordPattern = function(pattern, str) {
let map = new Map();
//将str转为数组
words = str.split(" ");
//遵循指完全匹配,长度不等,直接返回
if(pattern.length !== words.length) return false;
for (let i = 0; i < words.length; i++){
//判断map中是否存在该键,如果存在且值不等,则返回false
if (map.has(pattern[i])){
if (map.get(pattern[i]) !== words[i]) {
return false;
}
} else{
//如果不存在键,但值存在,也返回false
//由于map没有查看值的方法,只能去所有的值然后遍历,不知道这里有没有简便的处理方式
let hasValue = [...map.values()].some(value => value === words[i]);
if (hasValue) {
return false;
}
//键值都不存在,则添加键值对至map中
map.set(pattern[i], words[i]);
}
}
return true;
};
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词。
示例1:
输入: s = "anagram", t = "nagaram"
输出: true
示例2:
输入: s = "rat", t = "car"
输出: false
var isAnagram = function(s, t) {
if(s.length != t.length){
return false;
}
let arrs = s.split("").sort();
let arrt = t.split("").sort();
for(let i = 0 ; i < arrs.length; i++){
if(arrs[i] != arrt[i]){
return false;
}
}
return true;
};
对数组进行去重操作,只考虑数组中元素为数字或字符串,返回一个去重后的数组。
对数组进行去重操作,只考虑数组中元素为数字或字符串,返回一个去重后的数组。
// ES3
function unique(arr) {
var newArr = [];
for (var i = 0; i < arr.length; i++) {
var currElem = arr[i];
if (newArr.indexOf(currElem) < 0) {
newArr.push(currElem);
}
}
return newArr;
}
console.log(unique([1, 2, 1, 3]));
// ES5
function unique(arr) {
return arr.filter(function (elem, index) {
return arr.indexOf(elem) === index
});
}
console.log(unique([1, 2, 1, 3]));
// ES6
var arr = [1, 2, 1, 3];
console.log(Array.from(new Set(arr)));
// ES7
var arr = [1, 2, 1, 3];
console.log([...new Set(arr)]);
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
需要维护一个对象来记录每一个元素出现的次数,使用元素的值作为key,元素出现的次数作为value。之后再遍历这个对象,找到value为1的key。对应的key就是那个元素。
function singleNumber(nums) {
const obj = {};
for (let i = 0; i < nums.length; i++) {
obj[nums[i]] = obj[nums[i]] ? obj[nums[i]] + 1 : 1;
}
for (let key in obj) {
if (obj[key] === 1) {
return Number(key); // 由于 key 是 string ,因此我们这里需要转化下
}
}
}
console.log(singleNumber([2, 2, 1, 4, 4, 5, 5, 1, 8])); // 8
上面那种解法,创建了一个新的对象来储存结果,如果想不使用额外空间,明显是不行的。那么有没有办法可以只使用原来的数组来实现这个功能呢? 解决方案:异或操作
1.异或运算满足交换律、结合律。
1^2^...^n^...^n^...^1000,无论这两个n出现在什么位置,都可以转换成为1^2^...^1000^(n^n)的形式。
2.其次,对于任何数x,都有x^x=0,x^0=x。
所以1^2^...^n^...^n^...^1000 = 1^2^...^1000^(n^n)= 1^2^...^1000^0 = 1^2^...^1000(即序列中除了n的所有数的异或)。
异或运算是对于二进制数字而言的,比如说一个有两个二进制a、b,如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。
而javascript的按位异或(即^操作)操作,则会对两个数字相应的每一对比特位执行异或操作。
比如说 1 ^ 2,本质上其实是1和2的每一对比特位执行异或操作,等价于下面
00000000000000000000000000000001 // 数字1对应的二进制
^ 00000000000000000000000000000010 // 数字2对应的二进制
= 00000000000000000000000000000011 // 数字3对应的二进制
复制代码因此1^2的结果就为3啦。
那么如果两个相同的数字进行异或操作,结果就可想而知,答案为0啦。
如果是0和任何一个数字异或呢?结果是数字本身。
我们只需要遍历数组,将所有的值取异或,最终剩下的值,就是那个只出现一次的数字。 假设我们有一个数组,里面元素为[a, a, c, c, b, b, d]。那么我们对数组里的所有元素进行按位异或操作,即a ^ a ^ c ^ c ^ b ^ b ^ d,是不是就等价于0 ^ 0 ^ 0 ^ d = d。而d就是数组里只出现一次的元素。 那么我们可以扩展一下,对于任意满足某个元素只出现一次以外,其余每个元素均出现两次的数组,是不是可以通过这种方式来得到那个只出现一次的元素。
我们知道,两个相同的数字进行按位异或操作,得到的结果为0。并且任何数字与0进行按位异或,得到的结果是数字本身。那么假设我们有数组[a, b, b, a, c],将数组所有元素进行按位异或操作,即a ^ b ^ b ^ a ^ c,结果是不是等价于0 ^ c = c。同理可得,我们一个数组里只有某个元素只出现一次,其他都出现两次,那么将数组的所有元素都进行按位异或操作,那么结果是不是就等于那个只出现一次的元素。
/**
* 只存在一次的数字
* https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/1/array/25/
* @ param {number[]} nums
* @ return {number}
*/
function singleNumber(nums) {
for (let i = 1; i < nums.length; i++) {
nums[0] ^= nums[i];
}
return nums[0];
};
console.log(singleNumber([2, 2, 1, 4, 4, 5, 5, 1, 8]));
// 实现一个flatten方法,使得输入一个数组,该数组里面的元素也可以是数组,该方法会输出一个扁平化的数组。
// Example
let givenArr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
let outputArr = [1,2,2,3,4,5,5,6,7,8,9,11,12,12,13,14,10]
// 实现flatten方法使得
flatten(givenArr)——>outputArr
function flatten(arr){
var res = [];
for(var i=0;i<arr.length;i++){
if(Array.isArray(arr[i])){
// concat() 方法用于连接两个或多个数组。返回一个新数组。
res = res.concat(flatten(arr[i]));
}else{
res.push(arr[i]);
}
}
return res;
}
function flatten(arr){
// prev 上一次调用回调时返回的累积值。如果没有提供初始值,则将使用数组中的第一个元素。item 数组中正在处理的元素。
// array.reduce(function(accumulator, currentValue, currentIndex, arr), initialValue)
// accumulator 和currentValue的取值有两种情况:
// 如果调用reduce()时提供了initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值;
// 如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值。
return arr.reduce(function(prev,item){
return prev.concat(Array.isArray(item) ? flatten(item) : item);
},[]);
}
function flatten(arr){
while(arr.some(item => Array.isArray(item))){
arr = [].concat(...arr);
}
return arr;
}
异步函数并行执行,并控制并行数量
现在有个场景:
请你实现一个并发请求函数concurrencyRequest(urls, maxNum),要求如下:
要求最大并发数 maxNum 每当有一个请求返回,就留下一个空位,可以增加新的请求 所有请求完成后,结果按照 urls 里面的顺序依次打出(发送请求的函数可以直接使用fetch即可)
const preloadManger = (urls, maxCount = 5) => {
let count = 0; // 计数 -- 用于控制并发数
const createTask = () => {
if (count < maxCount) {
const url = urls.pop(); // 从请求数组中取值
if (url) {
// 无论请求是否成功,都要执行taskFinish
loader(url).finally(taskFinish);
// 添加下一个请求
count++;
createTask();
}
}
};
const taskFinish = () => {
count--;
createTask();
};
createTask();
};
// 进行异步请求
const loader = async (url) => {
const res = await fetch(url).then(res=>res.json());
console.log("res",res);
return res
}
const urls = [];
for (let i = 1; i <= 20; i++) {
urls.push(`https://jsonplaceholder.typicode.com/todos/${i}`);
}
preloadManger(urls, 5)
// 简洁版pLimit
// 异步逻辑并行执行,并控制并行数量
// 一个队列来保存任务,有两个时机考虑触发任务执行:
// 1. 开始的时候一次性执行最大并发数的任务
// 2. 然后每执行完一个启动一个新的
const shortPLimit = (concurrency) => {
// 传入并发数量
if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) {
throw new TypeError('Expected `concurrency` to be a number from 1 and up');
}
// 添加的并发任务要进行排队,所以我们准备一个 queue
const queue = [];
// 记录当前在进行中的异步任务
let activeCount = 0;
// 下一步处理自然就是把活跃任务数量减一,然后再跑一个任务
const next = () => {
activeCount--;
if (queue.length > 0) {
// 如果队列中还有任务,就再跑一个
queue.shift()();
}
};
// 计数,运行这个函数,改变最后返回的那个 promise 的状态
const run = async (fn, resolve, ...args) => {
activeCount++;
// 运行传入的异步函数
const result = (async () => fn(...args))();
resolve(result);
try {
// 等待异步函数执行完
await result;
} catch {}
// 执行完之后进行下一步处理
next();
};
// 把一个异步任务添加到 queue 中,并且只要没达到并发上限就再执行一批任务
const enqueue = (fn, resolve, ...args) => {
queue.push(run.bind(null, fn, resolve, ...args));
// 为了保证并发数量能控制准确,要等全部的微任务执行完再拿 activeCount 和 queue.length 来判断
(async () => {
await Promise.resolve();
if (activeCount < concurrency && queue.length > 0) {
// 如果活跃任务数量小于并发数量,就再跑一个
queue.shift()();
}
})();
};
// 返回一个添加并发任务的函数,我们把它叫做 generator。
// 依旧希望返回返回任务函数的promise的结果
const generator = (fn, ...args) =>
new Promise((resolve) => {
enqueue(fn, resolve, ...args);
});
return generator;
};
// 完整版pLimit
// 异步逻辑并行执行,并控制并行数量
// 一个队列来保存任务,有两个时机考虑触发任务执行:
// 1. 开始的时候一次性执行最大并发数的任务
// 2. 然后每执行完一个启动一个新的
const pLimit = (concurrency) => {
// 传入并发数量
if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) {
throw new TypeError('Expected `concurrency` to be a number from 1 and up');
}
// 添加的并发任务要进行排队,所以我们准备一个 queue
const queue = [];
// 记录当前在进行中的异步任务
let activeCount = 0;
// 下一步处理自然就是把活跃任务数量减一,然后再跑一个任务
const next = () => {
activeCount--;
if (queue.length > 0) {
// 如果队列中还有任务,就再跑一个
queue.shift()();
}
};
// 计数,运行这个函数,改变最后返回的那个 promise 的状态
const run = async (fn, resolve, ...args) => {
activeCount++;
// 运行传入的异步函数
const result = (async () => fn(...args))();
resolve(result);
try {
// 等待异步函数执行完
await result;
} catch {}
// 执行完之后进行下一步处理
next();
};
// 把一个异步任务添加到 queue 中,并且只要没达到并发上限就再执行一批任务
const enqueue = (fn, resolve, ...args) => {
queue.push(run.bind(null, fn, resolve, ...args));
// 为了保证并发数量能控制准确,要等全部的微任务执行完再拿 activeCount 和 queue.length 来判断
(async () => {
await Promise.resolve();
if (activeCount < concurrency && queue.length > 0) {
// 如果活跃任务数量小于并发数量,就再跑一个
queue.shift()();
}
})();
};
// 返回一个添加并发任务的函数,我们把它叫做 generator
const generator = (fn, ...args) =>
new Promise((resolve) => {
enqueue(fn, resolve, ...args);
});
// 为 generator 添加一些属性,方便外部获取当前的状态
Object.defineProperties(generator, {
activeCount: {
get: () => activeCount
},
pendingCount: {
get: () => queue.length
},
// 提供了一个清空任务队列的函数
clearQueue: {
value: () => {
queue.length = 0;
}
}
});
return generator;
};
// 测试代码
const limit = pLimit(2);
function asyncFun(value, delay) {
return new Promise((resolve) => {
console.log('start ' + value);
setTimeout(() => resolve(value), delay);
});
}
(async function () {
const arr = [
limit(() => asyncFun('aaa', 2000)),
limit(() => asyncFun('bbb', 3000)),
limit(() => asyncFun('ccc', 1000)),
limit(() => asyncFun('ccc', 1000)),
limit(() => asyncFun('ccc', 1000))
];
const result = await Promise.all(arr);
console.log(result);
})();