迭代器
const isIterable = obj => obj != null && typeof obj[Symbol.iterator] === 'function';
function iterative(fn) {
return function(subject, ...rest) {
// 如果对象是可迭代对象,就迭代次对象
if(isIterable(subject)) {
const ret = [];
for(let obj of subject) {
ret.push(fn.apply(this, [obj, ...rest]));
}
return ret;
}
return fn.apply(this, [subject, ...rest]);
}
}
const setColor = iterative((el, color) => {
el.style.color = color;
});
const els = document.querySelectorAll('li:nth-child(2n+1)');
setColor(els, 'red');
防抖
function debounce(fn, time = 100){
var timer;
return function(){
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, time);
}
}
红绿灯案例
const traffic = document.getElementById('traffic');
function wait(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function poll(...fnList){
let stateIndex = 0;
return async function(...args){
let fn = fnList[stateIndex++ % fnList.length];
return await fn.apply(this, args);
}
}
async function setState(state, ms){
traffic.className = state;
await wait(ms);
}
let trafficStatePoll = poll(setState.bind(null, 'wait', 1000),
setState.bind(null, 'stop', 1000),
setState.bind(null, 'pass', 1000));
(async function() {
// noprotect
while(1) {
await trafficStatePoll();
}
}());
###过程抽象 声明式
;(function () {
const app = document.getElementById('app');
//第一版
const stateList= [
{ state: 'pass', time: 1000 },
{ state: 'wait', time: 2000 },
{ state: 'stop', time: 2000 },
]
function start(app, stateList) {
index = 0
const applyState = function(index){
const{state, time} = stateList[index]
app.className = state
setTimeout(()=>{
applyState((index+1)%stateList.length);
}, time)
}
applyState(0)
}
// start(app, stateList);
//第二版
function wait (ms){
return new Promise(resolve =>setTimeout(resolve,ms))
}
async function setState(state, ms){
app.className = state
await wait(ms)
}
//声明式
async function start1(){
while(true){
await setState('pass', 1000);
await setState('wait', 2000)
await setState('stop', 3000)
}
}
//start1();
//第三版
//过程抽象
function poll(...actions){
let _index = 0
return async function(...args){
const action = actions[_index++ % actions.length]
return await action.apply(this, args)
}
}
//声明式
let trafficStatePoll = poll(
setState.bind(null,'pass',1000),
setState.bind(null,'wait',1000),
setState.bind(null,'stop',1000)
);
async function start2(){
while(true){
await trafficStatePoll();
}
}
start2()
})()