Promise.all 与 Promise.race
Promise.race = function (promises) {
let len = promises.length;
return new Promise((resolve, reject) => {
if (!len) {
resolve([])
}
for (let i = 0; i < len; i++) {
Promise.resolve(promises[i]).then((res) => {
resolve(res);
return;
}).catch((e) => {
reject(e);
return;
})
}
})
}
Promise.all = function (propmises) {
let len = propmises.length;
return new Promise((resolve, reject) => {
if (!len) return resolve([]);
let result = [];
function handlleData (data, index) {
result[index] = data;
if (len - 1 === index && !result.include(false)) {
resolve(result);
}
}
for (let i = 0; i < len; i++) {
Promise.resolve(promises[i]).then((res) => {
handlleData(res, i);
}).catch((e) => {
reject(e);
return;
})
}
})
}
EventBus 事件订阅监听
EventBus 在vue 中经常能用到,当然React 也是,经常用的油四个API on(监听事件) once(只触发一次事件,触发完后则将事件删除)
// 首先定义EventBus 类
class EventBus {
constructor() { }
handleBus = {}
$on (eventName, fn) {
if (!this.handleBus.hasOwnProperty(eventName)) {
this.handleBus[eventName] = [fn]
} else {
this.handleBus[eventName].push(fn)
}
}
$emit (eventName, payload) {
if (!this.handleBus.hasOwnProperty(eventName)) {
throw Error('没有此方法')
}
const eventFn = this.handleBus[eventName];
for (let item of eventFn) {
item(payload);
}
}
$off (eventName, fn) {
if (!this.handleBus.hasOwnProperty(eventName)) {
throw Error('没有此事件')
}
if (typeof fn !== 'function') {
this.handleBus[eventName] = []
} else {
let index = this.handleBus[eventName].findIndex((item, index) => item === fn);
if (index !== -1)
this.handleBus[eventName].splice(index, 1);
}
}
$once (eventName, fn) {
const myfunc = () => {
fn();
this.$off(eventName, fn);
}
this.$emit(eventName, myfunc)
}
}
快速排序
function quickSort (arr, l, r) {
let len = arr.length;
if (len <= 1) return arr;
l = typeof l === 'number' ? l : 0;
r = typeof r === 'number' ? r : len - 1;
let priv;
if (l < r) {
priv = getPriv(arr, l, r);
quickSort(arr, l, priv - 1);
quickSort(arr, priv + 1, r);
}
return arr;
}
function getPriv (arr, l, r) {
let stand = l;
let index = l + 1;
for (let i = index; i <= r; i++) {
if (arr[stand] > arr[i]) {
swap(arr, index, i);
index++;
}
}
swap(arr, stand, index - 1);
return index - 1
}
function swap (arr, l, r) {
let temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
}
console.log(quickSort([5, 4, 200, 2, 1]))
数组 reduce 方法简单实现
Array.prototype.reduce = function (fn) {
// 获取累加值
let accumulator;
// 获取默认值
let defaltValue = arguments.length > 1 ? arguments[1] : undefined;
//数组下标
let index = 0;
//数组
let arr = this;
// 边界判断
let len = arr.length;
if (!len && !defaltValue) {
throw Error('请输入一些数据')
}
if (typeof fn !== 'function') {
throw Error('回调函数应该是函数')
}
// 默认值存在
if (defaltValue) {
accumulator = defaltValue;
} else {
//默认值不存在,将数组第一个数设置为默认值
accumulator = arr[0];
index++;
}
// 循环相加
while (index < len) {
accumulator = fn.apply(undefined, [accumulator, arr[index], index, arr]);
index++;
}
return accumulator;
}
JS继承最佳实践 寄生式组合继承
原型链继承子代会共享一些引用数据, 构造函数继承会将函数重复创建, 组合继承会调用两次父类构造函数,并且会在子类实例与子类原型上都存在父类构造函数数据重复创建,寄生式构造函数相当于一个最佳版本,也是ES6 中extends 使用的方法
function Parent () {
this.color = ['yellow'];
}
Parent.prototype.sayName = function () {
console.log('Parent');
}
function Child () {
Parent.apply(this);
}
function F () {}
F.prototype = Parent.prototype
Child.prototype = new F();
const child = new Child ();
js 使用promise 进行并发控制
比如现在需要发30个请求,但是我需要控制每次最多发五个请求,当一个请求结束之后就会空出一个位置出来,这时候就可以发下一个请求。
function multiRequest (urls = [], maxNum) {
let len = urls.length;
const result = new Array(len).fill(false);
let count = 0;
return new Promise((resolve, reject) => {
while (count < len) {
next()
}
function next () {
let current = count++;
if (current >= len) {
!result.includes(false) && resolve(result)
return;
}
const url = urls[current];
fetch(url)
.then((res) => {
result[current] = res;
}).catch((e) => {
result[current] = res;
})
.finally(() => {
if (current < len) {
next()
}
})
}
})
}
函数柯里化
函数柯里化应该是对确定的函数的参数来进行分割,就像分割成多个函数调用一样,可以进行参数复用,本质上还是降低通用性,提高适用性。
function curry (func) {
let length = func.length;
return function curried (...args) {
if (args.length >= length) {
return func.apply(this, args);
} else {
return function (...args2) {
return func.apply(this, args.concat(args2));
}
}
}
}
function sum (a,b) {
return a + b;
}