回调函数未被调用

Callback functions not getting called

几天来我一直在为此苦苦挣扎...我似乎无法触发回调函数,我认为这是因为范围问题,因为当我将 "classes" 并手动测试所有功能等

我有一个 VisualTimer 对象

function VisualTimer(customConfig) {
    // Create a new Timer object
    var object = this;
    this.timer = new Timer(object, function(data) { this.timerUpdated(data); }, function (data) { this.timerFinished(data); });

    // Set default configuration
    this.config = {
        // The ID's of the timer's control elements
        pauseButtonId : "pause-timer",
        startButtonId : "start-timer",
        stopButtonId  : "stop-timer",
        // The ID's of the timer's display elements
        hoursDisplayId   : "hours-left",
        minutesDisplayId : "minutes-left",
        secondsDisplayId : "seconds-left",
        // The ID's of the timer's input elements
        hoursInputId   : "hours-left",
        minutesInputId : "minutes-left",
        secondsInputId : "seconds-left",
    };

    // Replace the default configuration if a custom config has been provided
    if (typeof(customConfig) == "object") this.config = customConfig;
}

这类似于对 Timer 对象的扩展,只是为了将底层计时器和可视控件分开。如您所见,我正在向 new Timer() "object" 注入每次更新时应调用的 VisualTimer 函数。但是,它不起作用。

定时器"object"定义如下

function Timer(callbackObject, updateCallback, finishedCallback) {

    // Define timer variables
    this.state   = Timer.stateStopped;

    this.callbackObject   = (typeof(callbackObject)   == "object")   ? callbackObject   : null;
    this.updateCallback   = (typeof(updateCallback)   == "function") ? updateCallback   : null;
    this.finishedCallback = (typeof(finishedCallback) == "function") ? finishedCallback : null;

    this.hours   = 0;
    this.minutes = 0;
    this.seconds = 0;

    // Save the values that the timer was initially set to
    this.startHours   = 0;
    this.startMinutes = 0;
    this.startSeconds = 0;

    /**
     * Store the setInterval() ID that is created when the timer is started
     * so that we can use this to clear it (stop the timer) later on.
     */
    this.interval = null;
}

具有启动、暂停、停止等功能,正如您在 "constructor" 中看到的,我有用于注入回调函数的变量,应在每次滴答后调用

Timer.prototype.tick = function(fireCallback) {
    fireCallback = (typeof(fireCallback) == "boolean") ? fireCallback : true;

    if (this.seconds > 0) {
        // If the seconds value is bigger than 0, subtract it by 1
        this.seconds -= 1;

        // Fire the update callback function
        console.log(this.hours + ":" + this.minutes + ":" + this.seconds);
        if (fireCallback && this.updateCallback != null) this.updateCallback.call(this.callbackObject, this.getCurrentValues());
    }
    else if (this.minutes > 0) {
        // If the seconds value is 0 but not the minutes value, subtract it by 1
        this.minutes -= 1;
        // And then also update the seconds value
        this.seconds  = 59;

        // Fire the update callback function
        console.log(this.hours + ":" + this.minutes + ":" + this.seconds);
        if (fireCallback && this.updateCallback != null) this.updateCallback.call(this.callbackObject, this.getCurrentValues());
    }
    else if (this.hours > 0) {
        // If neither the seconds nor the minutes value is bigger than 0 but the hours value is, subtract it by 1
        this.hours  -= 1;
        // And then also update the minutes and the seconds values
        this.minutes = 59;
        this.seconds = 59;

        // Fire the update callback function
        console.log(this.hours + ":" + this.minutes + ":" + this.seconds);
        if (fireCallback && this.updateCallback != null) this.updateCallback.call(this.callbackObject, this.getCurrentValues());
    }
    else {
        // Stop the timer
        this.stop(false);

        // Fire the finished callback function
        console.log("The timer has finished.");
        if (fireCallback && this.finishedCallback != null) this.finishedCallback.call(this.callbackObject, this.getInitialValues());
    }
};

滴答工作得很好,所以到目前为止代码没有任何问题,console.log() 输出正确所以定时器和滴答函数工作完美。不过,回调函数不会被触发。

我已经做了很多调试,所有函数都运行良好,所以问题肯定出在注入回调函数的实际调用上。其他一切都按预期工作。

这是应该在每次报价时触发的 updateCallback 函数

VisualTimer.prototype.timerUpdated = function(timerData) {
    if (typeof(timerData) == "object")
    {
        if (timerData.state == Timer.stateRunning) {
            // Update the timer's display elements with new values
            this.updateDisplayElements(timerData.hours, timerData.minutes, timerData.seconds);
        } 
        else if (timerData.state == Timer.statePaused) {
            // Make sure the correct values are displayed
            this.updateDisplayElements(timerData.hours, timerData.minutes, timerData.seconds);

            window.alert("The timer has been paused!");
        }
        else if (timerData.state == Timer.stateStopped) {
            // Reset the timer's input and display elements
            this.updateDisplayElements();
            this.updateInputElements();

            window.alert("The timer has been stopped!");
        }
    }
};

更新: 所有代码现在都可以作为 JSFiddle project.

第二次更新:

问题解决了!问题是 state 属性 从未发送到回调函数,因为本应命名为 getInitialValues() 的函数被意外命名为 getCurrentValues(),因此覆盖了该函数. getInitialValues() 不发送状态,但 getCurrentValues() 发送状态。更正函数名称后,一切正常:)

您没有将计时器的状态正确地传递到回调中,所以这段代码总是没有操作

VisualTimer.prototype.timerUpdated = function(timerData) {
    if (typeof(timerData) == "object")
    {
        if (timerData.state == Timer.stateRunning) { // THIS IS ALWAYS FALSE
            // Update the timer's display elements with new values
            this.updateDisplayElements(timerData.hours, timerData.minutes, timerData.seconds);
        } 
        else if (timerData.state == Timer.statePaused) {
            // Make sure the correct values are displayed
            this.updateDisplayElements(timerData.hours, timerData.minutes, timerData.seconds);

            window.alert("The timer has been paused!");
        }
        else if (timerData.state == Timer.stateStopped) {
            // Reset the timer's input and display elements
            this.updateDisplayElements();
            this.updateInputElements();

            window.alert("The timer has been stopped!");
        }
    }
};

因为 timerData 上实际上没有 state 属性。这是您设置状态的地方。此时this对象就是Timer对象本身

    // Set the current state to running
    this.state = Timer.stateRunning;

然后当你调用上面的 noop 代码时,你会做:

if (fireCallback && this.updateCallback != null) this.updateCallback.call(this.callbackObject, this.getCurrentValues());

this 设置为 this.callbackObject 而没有 state 属性.

正在调用回调,只是调用不正确。