这些功能似乎是乱序执行的

时间:2014-01-16 18:06:33

标签: javascript events backbone.js

最奇怪的事情发生在我身上。我有一些似乎正在以错误的顺序执行的javascript。这吓坏了我!观察:

代码

    handleKeyDown: function (e) {
        console.log("handleKeyDown");
        var key = e.which;
        var text = this.ui.$input.val();

        if (_.isFunction(this[key])) {
            // call the appropriate handler method
            this[key](text, e);

            console.log("before announceEdits");
            this.announceEdits();
        }

        if (key === ENTER || key === ESC) {
            console.log("fired field:key:down");
            this.trigger("field:key:down", { editable: this, restore: (key === ESC) });
        }
    },

    announceEdits: function () {
        console.log("announceEdits");
        var edits = this.getEdits();

        console.log("edits: %o", edits.data);
        console.log("fired field:edits");
        this.trigger("field:edits", edits);
    },

    /* gather all the existing taggies */
    getEdits: function () {
        var data = this.$taggies().map(function (index, taggy) {
            return $(taggy).data("value");
        }).toArray();

        var edits = {
            attribute: "tags",
            data: data
        };

        return edits;
    },

当我运行此代码时,这些函数似乎是乱序执行的。这是firefox控制台中上面代码的输出:

输出

Firefox console output

请注意,我们在获得before announceEdits之前已经announceEdits了很长时间,这是annouceEdits函数中的第一行...我对世界的理解让我相信这是错误的。

我做了什么

现在,我考虑了以下内容:

  1. 控制台语句可能正在缓冲或某些问题,导致它们出现故障。
  2. 这可能与MarionetteJS处理事件的方式有关。
  3. 相信这可能是偶然的怪异,我试图删除触发的调用(只是通过注释掉触发事件的行)。删除触发器后,日志语句仍然不按顺序显示。因此,MarionetteJS的事件实现(也就是说,BackboneJS的事件实现^ o ^ //)不会导致似乎

    我也认为这不是一个日志语句缓冲区问题,因为事件本身是乱序处理的(即我希望在处理第一个事件之后的数据不按顺序处理处理第二个事件的时间)。这导致代码以我想要的方式“不工作”(但是,见下文)。

    在我的探索中,我试图缩小范围。我这样修改了代码,以简化代码:

        if (_.isFunction(this[key])) {
            // call the appropriate handler method
            this[key](text, e);
    
            console.log("before announceEdits");
            console.log("announceEdits");
            var edits = this.getEdits();
    
            console.log("edits: %o", edits.data);
            console.log("fired field:edits");
            this.trigger("field:edits", edits);
        }
    

    这样我就不会进入子程序了。运行此代码,控制台语句以正确的顺序显示。更有趣的是,在这种情况下,事件也会按照我期望的顺序触发和处理!这段代码有效,但子程序没有。

    我试图创建这个代码的小提琴,但jsfiddle似乎不喜欢Backbone(我尝试将库包含为外部库,但这似乎不起作用)。我确实创造了this fiddle,只是为了让自己放心,在世界的某个地方仍然存在着正常的摇滚。

    更新:我改变了小提琴,以便主要功能本身就是一个处理程序。小提琴中的一切仍然可以正常工作。

    我认为世界如何运作

    函数创建执行完成的堆栈帧。如果函数调用另一个函数,则会将新的堆栈帧推送到堆栈。如果函数触发事件,则会创建一条消息,该消息将被推送到消息队列中。每当(我不清楚)堆栈为空时,弹出队列中的下一条消息,然后调用该消息的所有处理程序。

    在这个模型中,毫无疑问,事件应该按照我期望的顺序发生(来自第二个列表的顺序)。我们应首先进入announceEdits,将field:edits消息推送到队列,然后弹出并推送field:key:down消息。然后应该运行field:edits的处理程序,最后运行field:key:down的处理程序。

    问题

    是否有任何可能导致这些功能无序执行的内容?或者更有可能的是:是否有任何可能导致这些功能出现被无序执行?

    如果这是我的理解问题:我哪里出错?

    如果这最终成为由拼写错误引起的事情,请记住我们都是程序员,而且我们都会撕掉头发并且有时会在阴影中咆哮。

1 个答案:

答案 0 :(得分:0)

睡在上面。在当下的热度中,每个虫子都是来自另一个世界的神秘力量。退出问题,从头开始。一切都会变得清晰。

我今天早上来了,在debugger的开头放了一个handleKeyDown并立即看到了什么问题。它不是我上面给出的代码,当然,这不是javascript如何工作的问题(显然!)。我早些时候曾经去过announceEdits进行辩护,以减轻我一直以来的头痛。

好消息是,我对事件处理工作方式的理解似乎没有问题。