2013-10-10 34 views
1

我在設計一個通過回調暴露其行爲的類時遇到了麻煩。是的,我的方法適用於我,但也似乎太複雜。Javascript回調管理

爲了說明我畫下面的圖片的問題。我希望對你瞭解班級/模特很有幫助。

enter image description here

在我的方法,我用一些陣列控股用戶定義的回調函數。

.... 

rocket.prototype.on = function(eventName, userFunction) { 
this.callbacks[eventName].push(userFunction); 
} 

rocket.prototype.beforeLunch = function(){ 
userFunctions = this.callbacks['beforeLunch'] 
for(var i in userFunctions) 
    userFunctions[i](); // calling the user function 
} 

rocket.prototype.lunch = function() { 
    this.beforeLunch(); 
    ... 
} 

.... 

var myRocket = new Rocket(); 

myRocket.on('beforeLunch', function() { 
// do some work 
console.log('the newspaper guys are taking pictures of the rocket'); 
}); 

myRocket.on('beforeLunch', function() { 
// do some work 
console.log('some engineers are making last checks '); 
}); 

我想知道最常用的方法是什麼。我想我可以使用承諾或其他庫來使這個實現更容易理解。在這張使用回調的幻燈片中被認爲是邪惡的。 http://www.slideshare.net/TrevorBurnham/sane-async-patterns

那麼,我應該使用承諾這樣的圖書館還是繼續並加強我的方法?

+0

我沒有得到你真正想做的事情。動畫?或者這幅圖描述了你的世界模型? – Bergi

+0

我編輯問題。現在它更清楚。 – Samed

+0

我不會將Javascript用於任何人們生命危險的重要軟件。 – tomsv

回答

0
var Rocket = function() { 

    this.timer = null; 
    this.velocity = 200; 
    this.heightMoon = 5000; 
    this.goingToMoon = true; 

    this.rocketStatus = { 
     velocity: null, 
     height: 0, 
     status: null 
    }; 

    this.listener = { 
    }; 
} 

Rocket.prototype.report = function() { 
    for (var i in this.rocketStatus) { 
     console.log(this.rocketStatus[i]); 
    }; 
}; 

Rocket.prototype.on = function (name,cb) { 

    if (this.listener[name]){ 
     this.listener[name].push(cb); 
    }else{ 
     this.listener[name] = new Array(cb); 
    } 
}; 

Rocket.prototype.initListener = function (name) { 
    if (this.listener[name]) { 
     for (var i = 0; i < this.listener[name].length; i++) { 
      this.listener[name][i](); 
     } 
     return true; 
    }else{ 

     return false; 
    }; 
} 

Rocket.prototype.launch = function() { 

    this.initListener("beforeLaunch"); 

    this.rocketStatus.status = "Launching"; 
    this.move(); 

    this.initListener("afterLaunch"); 
} 

Rocket.prototype.move = function() { 

    var that = this; 

    that.initListener("beforeMove"); 

    if (that.goingToMoon) { 
     that.rocketStatus.height += that.velocity; 
    }else{ 
     that.rocketStatus.height -= that.velocity; 
    }; 

    that.rocketStatus.velocity = that.velocity; 

    if (that.velocity != 0) { 
     that.rocketStatus.status = "moving"; 
    }else{ 
     that.rocketStatus.status = "not moving"; 
    }; 

    if (that.velocity >= 600){ 
     that.crash(); 
     return; 
    } 
    if (that.rocketStatus.height == 2000 && that.goingToMoon) 
     that.leaveModules(); 


    if (that.rocketStatus.height == that.heightMoon) 
     that.landToMoon(); 


    if (that.rocketStatus.height == 0 && !that.goingToMoon){ 
     that.landToEarth(); 
     return; 
    } 
    that.report(); 



    that.initListener("afterMove"); 

    that.timer = setTimeout(function() { 
     that.move(); 
    },1000) 
} 


Rocket.prototype.stop = function() { 

    clearTimeout(this.timer); 
    this.initListener("beforeStop"); 
    this.velocity = 0; 
    this.rocketStatus.status = "Stopped"; 
    console.log(this.rocketStatus.status) 

    this.initListener("afterStop"); 
    return true; 
} 

Rocket.prototype.crash = function() { 

    this.initListener("beforeCrash"); 

    this.rocketStatus.status = "Crashed!"; 
    this.report(); 
    this.stop(); 
    this.initListener("afterCrash"); 
} 



Rocket.prototype.leaveModules = function() { 

    this.initListener("beforeModules"); 

    this.rocketStatus.status = "Leaving Modules"; 

    this.initListener("afterModules"); 
} 

Rocket.prototype.landToMoon = function() { 

    this.initListener("beforeLandToMoon"); 

    this.rocketStatus.status = "Landing to Moon"; 
    this.goingToMoon = false; 

    this.initListener("afterLandToMoon"); 
} 

Rocket.prototype.landToEarth = function() { 

    this.initListener("beforeLandToEarth"); 

    this.stop(); 
    this.rocketStatus.status = "Landing to Earth"; 

    this.initListener("afterLandToEarth"); 
} 

Rocket.prototype.relaunch = function() { 

    this.initListener("beforeRelaunch"); 

    this.timer = null; 
    this.velocity = 200; 
    this.heightMoon = 5000; 
    this.goingToMoon = true; 

    this.rocketStatus = { 
     velocity: 200, 
     height: 0, 
     status: "relaunch" 
    }; 

    this.launch(); 

    this.initListener("afterRelaunch"); 
} 

init;

var rocket = new Rocket(); 

rocket.on("afterLaunch", function() {console.log("launch1")}) 
rocket.on("afterLandToMoon", function() {console.log("land1")}) 
rocket.on("beforeLandToEarth", function() {console.log("land2")}) 
rocket.on("afterMove", function() {console.log("move1")}) 
rocket.on("beforeLaunch", function() {console.log("launch2")}) 

rocket.launch(); 

您可以在任何事件之前或之後添加任何函數。

這是我對這個有點問題的解決方案。我沒有使用任何特殊的方法。我只是想知道這個問題有沒有什麼好的做法。我挖掘了一些承諾,推遲了,但我無法做到這一點。有任何想法嗎 ?