Created
March 29, 2018 07:59
-
-
Save chhpt/a3d0d693a7d982b7bcffb4c0d65a6e18 to your computer and use it in GitHub Desktop.
实现交通灯的顺序变化
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 实现较好的封装 | |
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']); | |
// 问题:可重用性不好 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 实现较好的可重用性 | |
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); | |
// 问题:等待时间可能会变化 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 对时间进行抽象 | |
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(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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