Skip to content

Instantly share code, notes, and snippets.

@chhpt
Created March 29, 2018 07:59
Show Gist options
  • Save chhpt/a3d0d693a7d982b7bcffb4c0d65a6e18 to your computer and use it in GitHub Desktop.
Save chhpt/a3d0d693a7d982b7bcffb4c0d65a6e18 to your computer and use it in GitHub Desktop.
实现交通灯的顺序变化
// 实现较好的封装
const traffic = document.getElementById('traffic');
function start(traffic, statelist) {
var currentStateIndex = 0;
setinterval(function() {
var state = statelist[currentstateindex];
traffic.className = state;
currentStateIndex = (currentStateIndex + 1) % stateList.length;
}, 2000);
}
start(traffic, ['wait', 'stop', 'pass']);
// 问题:可重用性不好
// 实现较好的可重用性
const traffic = document.getElementById('traffic');
function poll(...fnList) {
let stateIndex = 0;
return function(...args) {
let fn = fnList[stateIndex++ % fnList.length];
return fn.apply(this, args);
};
}
function setstate(state) {
traffic.className = state;
}
let trafficStatePoll = poll(
setstate.bind(null, 'wait'),
setstate.bind(null, 'stop'),
setstate.bind(null, 'pass')
);
setinterval(trafficStatePoll, 2000);
// 问题:等待时间可能会变化
// 对时间进行抽象
const traffic = document.getElementById('traffic');
function wait(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
function setState(state) {
traffic.className = state;
}
function reset() {
 // 返回 resolved 状态的 Promise 对象
 Promise.resolve()
.then(setState.bind(null, 'wait'))
.then(wait.bind(null, 1000))
.then(setState.bind(null, 'stop'))
.then(wait.bind(null, 2000))
.then(setState.bind(null, 'pass'))
.then(wait.bind(null, 3000))
.then(reset);
}
reset();
const traffic = document.getElementById('traffic');
function TrafficProtocol(el, reset) {
this.subject = el;
this.autoReset = reset;
this.stateList = [];
}
TrafficProtocol.prototype.putState = function(fn) {
this.stateList.push(fn);
};
TrafficProtocol.prototype.reset = function() {
let subject = this.subject;
this.statePromise = Promise.resolve();
this.stateList.forEach(stateFn => {
this.statePromise = this.statePromise.then(() => {
return new Promise(resolve => {
stateFn(subject, resolve);
});
});
});
if (this.autoReset) {
this.statePromise.then(this.reset.bind(this));
}
};
TrafficProtocol.prototype.start = function() {
this.reset();
};
var traffic = new TrafficProtocol(traffic, true);
traffic.putState(function(el, next) {
el.className = 'wait';
setTimeout(next, 1000);
});
traffic.putState(function(el, next) {
el.className = 'stop';
setTimeout(next, 2000);
});
traffic.putState(function(el, next) {
el.className = 'pass';
setTimeout(next, 3000);
});
traffic.start();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment