- promise
- async await
- 防抖,节流
- 柯里化
- 实现new,call, apply, bind
- lazyman
- flatten 数组扁平化
- 发布订阅
- 斐波那契数列生成
- 错误重传封装
promise
async await
function async(genF){
function spawn(genF) {
return new Promise(function(resolve, reject) {
const gen = genF();
function step(nextF) {
let next;
try {
next = nextF();
} catch(e) {
return reject(e);
}
if(next.done) {
return resolve(next.value);
}
Promise.resolve(next.value).then(function(v) {
step(function() { return gen.next(v); });
}, function(e) {
step(function() { return gen.throw(e); });
});
}
step(function() { return gen.next(undefined); });
});
}
return spawn(genF);
}
防抖,节流
防抖:特定时间间隔之内不触发时调用
节流:特定时间间隔之内调用一次
// 防抖 特定时间间隔内不触发时才执行
function debounce(func, duration){
let timer;
return function(){
const context = this;
const args = [...arguments];
if(timer){
clearTimeout(timer);
timer = null;
}
timer = setTimeout(function(){
func.apply(context, args);
}, duration);
}
};
// 节流 特定时间间隔内只发生一次
function throttle(func, duration){
let timer;
return function(){
const context = this;
const args = [...arguments];
if(timer){
return;
}
timer = setTimeout(function(){
func.apply(context, args);
clearTimeout(timer);
timer = null;
}, duration);
}
}
柯里化
在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
在直觉上,柯里化声称“如果你固定某些参数,你将得到接受余下参数的一个函数”。
说人话就是把接受多个参数的函数转为多个嵌套的单个参数的函数。我们使用场景的职责链模式是柯里化的例子,每个函数只处理自己关心的参数。
柯里化的好处:
- 参数复用:一些固定参数不用重复传,比如类型校验函数。
- 延迟调用:bind函数
- 提前返回: 如对DOM事件封装等,自执行函数中提前返回一个函数。下次不用做重复判断了。
// 柯里化
function currying(fn){
// 函数的参数个数
const max = fn.length;
let arr = [];
const closure = function(...args){
arr = arr.concat(args);
// 没调用完,返回函数
if(arr.length < max){
return closure;
}else{
return fn(...arr);
}
};
return closure;
}
function add(x, y, z) {
return x + y + z
}
curriedAdd = currying(add)
console.log('柯里化', curriedAdd(1, 2)(3));
实现new, call, apply, bind
// call
Function.prototype.callFunc = function callFunc(){
const self = [...arguments][0];
const args = [...arguments].slice(1);
self.fn = this;
const res = self.fn(...args);
delete self.fn;
return res;
}
// apply
Function.prototype.applyFunc = function applyFunc(){
const self = [...arguments][0];
const args = [...arguments][1];
self.fn = this;
const res = self.fn(...args);
delete self.fn;
return res;
}
// bind
Function.prototype.bind = function(){
let self = this;
let context = [...arguments][0];
let args = [...arguments].slice(1);
return function(){
return self.apply(context, [...args, ...arguments])
}
};
var getVal = function(z, m){
return this.val + this.y + z + m;
}
console.log(getVal.callFunc({
val: 456,
y: 123
},4,5));
console.log(getVal.applyFunc({
val: 456,
y: 123
}, [4,5]))
// 实现 new
function Create(Con, arguments){
const Con = [...arguments][0];
const args = [...arguments].slice(1);
// 创建一个新对象
const obj = {};
// 指定原型
obj.setPropertyOf(Con.prototype);
// 执行构造函数
const res = Con.call(obj, ...args);
// 返回对象
return typeof res === 'object' ? res : obj;
}
lazyman
flatten 数组扁平化
// 数组扁平化
function flatten(arr = []){
if(!arr.length){
return arr;
}
let res = [];
arr.forEach((item, index) => {
if(!Array.isArray(item)){
res.push(item);
}else{
res = res.concat(flatten(item));
}
});
return res;
}
发布订阅
[发布]
斐波那契数列生成
// 斐波那契数列
function fibonacci(n){
const arr = [0 ,1];
let a = 0;
let b = 1;
while(arr.length < n){
[a, b] = [b, a + b];
arr.push(b);
}
return arr;
}
console.log('斐波那契数列', fibonacci(8));
错误重传封装
// 重传
function retry(promiseFn, times = 3, duration = 200){
return new Promise((resolve, reject) => {
const handler = () => {
promiseFn().then(res => resolve(res)).catch(err => {
times--;
if(!times){
reject(err);
}else{
setTimeout(handler, duration);
}
});
};
handler();
});
}
function fetchData() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('server unavailable')
reject('server unavailable');
}, 500);
});
}
retry(fetchData)