setTimeout
function throttle(func, delay){
let startTime = 0;
return function(){
const curTime = new Date();
if(curTime-startTime > delay){
func.apply(this, arguments);
startTime = curTime;
}
}
}
setTimeout
function throttle(func, delay){
let timer;
return function(...args){
if(timer) return;
let self = this;
// let args = arguments;
setTimeout(() => {
func.apply(self, args);
clearTimeout(timer);
}, delay);
}
}
function debounce(func, delay){
let timer;
return function(...args){
const self = this;
// const args = arguments
clearTimeout(timer);
setTimeout(() => {
func.apply(this, args)
}, delay);
}
}
// function curry(fn, ...args) {
// length = fn.length;
// return function(){
// const newArgs = args.concat(Array.prototype.slice.call(arguments));
// if(newArgs.length < length) {
// return curry.call(this, fn, ...newArgs);
// } else {
// return fn.apply(this, newArgs);
// }
// }
// }
function curry(fn, ...args) {
length = fn.length;
return function(...newArgs){
const mergedArgs = [...args, ...newArgs];
if((mergedArgs.length) < length) {
return curry.call(this, fn, ...mergedArgs);
} else {
return fn.apply(this, mergedArgs);
}
}
}
Promise.all
function all(promises) {
let len = promises.length;
let res = [];
let count = 0;
if (len) {
return new Promise(function (resolve, reject) {
for(let i=0; i<len; i++) {
let promise = promises[i];
promise.then(response => {
res[i] = response;
++count;
if(count === len) resolve(res);
}, error => {
reject(error);
})
}
})
}
}
function all2(promises){
const results = [];
const merged = promises.reduce(
(acc, p) => acc.then(() => p).then(r => results.push(r)),
Promise.resolve(null));
return merged.then(() => results);
};
Promise.race
resolve
或reject
了,后续的resolve
或reject
就无效了function race(...promises) {
return new Promise((res, rej) => {
promises.forEach(p => p.then(res).catch(rej));
});
}
new
操作符function New(func, ...args) {
let res = Object.create(func.prototype, {});;
let ret = func.apply(res, args);
// if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
if (ret instanceof Object){
return ret;
}
return res;
}
call
与 apply
Function.prototype.call = function(context, ...args){
const funcName = Symbol();
context[funcName] = this;
const result = context[funcName](...args);
delete context[funcName];
return result;
}
Function.prototype.apply = function(context, args){ // 与call的唯一不同之处
const funcName = Symbol();
context[funcName] = this;
const result = context[funcName](...args);
delete context[funcName];
return result;
}
bind
Function.prototype.bind = function(content, ...args) {
// if(typeof this != "function") {
// throw Error("not a function")
// }
let fn = this;
let resFn = function() {
return fn.apply(this instanceof resFn ? this : content,args.concat(...arguments) )
}
function tmp() {}
tmp.prototype = this.prototype;
resFn.prototype = new tmp();
return resFn;
}
function retry(p, times, delay) {
return new Promise((resolve, reject) => {
function attempt() {
p().then(
(value) => resolve(value),
(reason) => times-- ? attempt() : resolve(reason)
);
}
attempt();
});
}
function chainPromise(promiseFactories) {
const results = [];
return new Promise((resolve, reject) => {
const chainedPromise = promiseFactories.reduce(
(pre, cur) => pre.then(() => cur())
.then((value) => results.push(value), (reason) => reject(reason)),
Promise.resolve(null)
);
chainedPromise.then(() => resolve(results));
});
}
function chainPromise(promiseFactories, times) {
const results = [];
return new Promise((resolve, reject) => {
const chainedPromise = promiseFactories.reduce(
(pre, cur) => pre.then(() => retry(cur, times))
.then((value) => results.push(value), (reason) => reject(reason)),
Promise.resolve(null)
);
chainedPromise.then(() => resolve(results));
});
}
// https://www.ruanyifeng.com/blog/2015/05/async.html
function* asyncFun() {
let a = yield Promise.resolve("A");
let b = yield new Promise((resolve) => setTimeout(() => resolve("B"), 1000));
return a + b;
}
function spawn(genF) {
return new Promise(function (resolve, reject) {
const gen = genF();
// move one step forward
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(
(v) => step(() => gen.next(v)),
(e) => step(() => gen.throw(e))
);
}
step(() => gen.next(undefined));
});
}
spawn(asyncFun).then((value) => console.log(value));
参考资料: