简体   繁体   English

回调函数未调用

[英]Callback functions not getting called

I've been struggling with this for days now... I just can't seem to get the callback functions to fire, and I assume it's because of a scope problem since the code works when I separate the "classes" and manually test all the functions etc. 我已经为此苦苦挣扎了好几天了……我似乎无法触发回调函数,并且我认为这是因为范围问题,因为当我分离“类”并手动测试时,代码起作用了所有功能等

I have a VisualTimer object 我有一个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;
}

that serves like an extension to a Timer object, just to separate the underlying timer and the visual controls. 就像对Timer对象的扩展一样,只是将基础计时器和可视控件分开。 As you can see I'm injecting the new Timer() "object" with the VisualTimer functions that should be called on each update. 如您所见,我正在向新的Timer()“对象”注入应在每次更新时调用的VisualTimer函数。 However, it doesn't work. 但是,它不起作用。

The Timer "object" is defined as follows 计时器“对象”定义如下

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

with functions for starting, pausing, stopping, etc. and as you can see in the "constructor" I have variables for injecting callback functions that should be called after each tick 具有启动,暂停,停止等功能,正如您在“构造函数”中看到的那样,我有一些变量用于注入应在每个刻度之后调用的回调函数

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

The ticking works perfectly fine, so there's nothing wrong in the code up until now, and the console.log() outputs correctly so the timer and the tick function works perfect. 滴答声可以很好地工作,因此到目前为止,代码中没有任何问题,console.log()可以正确输出,因此计时器和滴答声功能可以正常工作。 The callback function doesn't get fired, though. 但是,不会触发回调函数。

I've done a lot of debugging, and all functions works perfectly so the problem is definitely in the actual calling of the injected callback functions. 我已经进行了很多调试,所有功能均正常运行,因此问题肯定出在实际调用的回调函数调用上。 Everything else works as expected. 其他所有工作均按预期进行。

This is the updateCallback function that should be fired on each tick 这是应该在每个刻度上触发的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!");
        }
    }
};

UPDATE: All the code is now available as a JSFiddle project . 更新:所有代码现在都可以作为JSFiddle项目获得

2nd UPDATE: 第二次更新:

Problem solved! 问题解决了! The issue was that the state property was never sent to the callback function due to the function that was supposed to be named getInitialValues() was accidentally named getCurrentValues() and therefore overwrote that function. 问题在于state属性从未被发送到回调函数,这是因为应该将其命名为getInitialValues()的函数被意外命名为getCurrentValues() ,因此重写了该函数。 getInitialValues() doesn't send the state, but getCurrentValues() do. getInitialValues()不会发送状态,但是getCurrentValues()会发送状态。 After correcting the function names it all worked perfectly :) 更正函数名称后,它们都可以正常工作:)

You are not passing the state of the timer into the callback properly, so this code always no-ops 您没有将计时器的状态正确地传递到回调中,因此此代码始终为“无操作”

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!");
        }
    }
};

because there is in fact no state property on timerData . 因为实际上在timerData上没有state属性。 Here is where you set the state. 在这里设置状态。 At this point the this object is the Timer object itself 此时, this对象是Timer对象本身

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

Then when you call the above noop code, you do: 然后,当您调用上述noop代码时,您将执行以下操作:

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

Which sets this to this.callbackObject which does not have a state property. 这台thisthis.callbackObject不具有state性质。

The callbacks are getting called, just not properly. 回调被调用,只是不正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM