Skip to content

Instantly share code, notes, and snippets.

@nexpr
Created December 4, 2015 09:18
Show Gist options
  • Save nexpr/9a63004295587dd9ea13 to your computer and use it in GitHub Desktop.
Save nexpr/9a63004295587dd9ea13 to your computer and use it in GitHub Desktop.
function FlowControl(auto){
this.auto = !!auto
this.finish = {}
this.wait = []
this.units = {}
if(document.readyState === "complete"){
this.set("load")
}else{
window.addEventListener("load", function(){
this.set("load")
}, false)
}
}
FlowControl.prototype.add = function(name, action, opts){
var unit = {
name: name,
action: action,
after: (opts && opts.after) || [],
args: (opts && opts.args) || [],
bind: (opts && opts.bind) || null,
}
if(typeof unit.action !== "function"){
throw new Error("Action is not function.")
}
if(! (unit.after instanceof Array)){
unit.after = [unit.after]
}
if(! (unit.args instanceof Array)){
unit.args = [unit.args]
}
if(unit.name !== null){
if(unit.name in this.units){
throw new Error("name [[" + unit.name + "]] already exists.")
}
this.units[unit.name] = unit
}
this.wait.push(unit)
if(this.auto){
this._run()
}
}
FlowControl.prototype.add_cb = function(name, action, opts){
var that = this
return function(/*arguments*/){
opts.args = [].slice.call(arguments)
that.add(name, action, opts)
}
}
FlowControl.prototype.set = function(name){
if(name in this.units){
throw new Error("name [[" + unit.name + "]] already exists.")
}
this.finish[name] = {name: name}
this.units[name] = {name: name}
if(this.auto){
this._run()
}
}
FlowControl.prototype._run = function(){
var before_length, after_length
var that = this
do{
before_length = that.wait.length
that.wait = that.wait.filter(function(e,i,a){
if(e.after.filter(function(ee){
return !(ee in that.finish)
}).length === 0){
e.action.apply(e.bind, e.args)
if(e.name !== null)
that.finish[e.name] = e
return false
}
return true
})
after_length = that.wait.length
}while(before_length !== after_length)
}
FlowControl.prototype.run = function(auto){
this._run()
if(auto!=null){
this.auto = !!auto
}
}
FlowControl.prototype.stop = function(){
this.auto = false
}
/////////////sample///////////////
var fc = new FlowControl
fc.add("b", function(){console.log("b")}, {after:["t","g"]})
fc.run()
console.log("runしてもbはまだ出力されない")
fc.add("g", function(){console.log("g")})
console.log("gは待機するものないけどautoじゃないときはrunするまで実行されない")
fc.add("t", function(){console.log("t")})
fc.run()
console.log("****************")
//
var fc = new FlowControl(true)
fc.add("b", function(){console.log("b")}, {after:["t","g"]})
fc.run()
console.log("runしてもbはまだ出力されない")
fc.add("g", function(){console.log("g")})
console.log("autoなのでgが出力される")
fc.add("t", function(){console.log("t")})
console.log("****************")
//
var obj = {xx:1,yy:2}
var fc = new FlowControl(true)
fc.add("a", function(a,b,c){console.log("a | args =>",a,b,c)}, {args:[1,2,3], after:"b"})
fc.add("b", function(){console.log("b | this =>", this)}, {bind:obj, after:"c"})
setTimeout(fc.add_cb("c", function(a,b){console.log("c | args =>",a,b)}, {after:"d"}), 1000, "zzz1", "zzz2")
fc.add("d", function(){console.log("d | ")})
fc.add(null, function(){console.log("Action that name is null can be registered any number of times.")})
fc.add(null, function(){console.log("Action that name is null can be registered any number of times.")})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment