1

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

为了说明问题,我画了下图。我希望它对您了解类/模型有用。

在此处输入图像描述

在我的方法中,我使用一些包含用户定义回调函数的数组。

....

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

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

那么,我应该使用诸如 promise 之类的库还是继续并增强我的方法?

4

1 回答 1

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

您可以在任何事件之前或之后添加任何功能。

这是我对此类问题的解决方案。我没有使用任何特殊方法。我只是想知道对于此类问题是否有任何好的做法。我挖掘了一些承诺,推迟了,但我无法做到这一点。有任何想法吗 ?

于 2013-10-28T14:10:47.240 回答