Javascript回调管理

时间:2013-10-10 10:43:20

标签: javascript callback promise jquery-deferred deferred

我在设计一个通过回调公开其动作的类时遇到了麻烦。是的,我的方法适合我,但也似乎太复杂了。

为了说明问题,我画了下面的图片。我希望你理解这个类/模型是有用的。

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 ');
});

我想知道最常用的方法是什么。我想我可以使用promises或其他库来使这个实现更容易理解。在此幻灯片中使用回调被认为是邪恶的。 http://www.slideshare.net/TrevorBurnham/sane-async-patterns

那么,我应该使用诸如承诺或继续等库来增强我的方法吗?

1 个答案:

答案 0 :(得分: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");
}

初​​始化;

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();

您可以在任何活动之前或之后添加任何功能。

这是我解决这个问题的方法。我没有使用任何特殊方法。我只是想知道这有什么好的做法就像问题一样。我挖了一些承诺,推迟但我无法做到这一点。有什么想法吗?