我正在构建一个通用的Backbone视图来管理多个子视图。有时在渲染之前需要执行一些逻辑来准备这些视图。我考虑使用Backbone事件来启用一个名为pre_render的钩子,例如:
view = new (this.child_view);
this.trigger('pre_render', view);
view.render();
trigger()
调用的事件会同步执行,从而保证它们都会在render()
行被调用之前完成吗?
我正在构建一个通用的Backbone视图来管理多个子视图。有时在渲染之前需要执行一些逻辑来准备这些视图。我考虑使用Backbone事件来启用一个名为pre_render的钩子,例如:
view = new (this.child_view);
this.trigger('pre_render', view);
view.render();
trigger()
调用的事件会同步执行,从而保证它们都会在render()
行被调用之前完成吗?
基本上,是的,它是同步的。
以下是来源文件的相关部分:
trigger: function(name) {
if (!this._events) return this;
var args = slice.call(arguments, 1);
if (!eventsApi(this, 'trigger', name, args)) return this;
var events = this._events[name];
var allEvents = this._events.all;
if (events) triggerEvents(this, events, args);
if (allEvents) triggerEvents(this, allEvents, arguments);
return this;
},
import函数是triggerEvents
,实际上它会调用处理程序。根据注释,它只是一个经过优化的分发器。请注意,它们都在调用.call()
和.apply()
,因此回调将在控制权交还给调用者之前完成。
var triggerEvents = function(obj, events, args) {
var ev, i = -1, l = events.length;
switch (args.length) {
case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx);
return;
case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0]);
return;
case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1]);
return;
case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1], args[2]);
return;
default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
}
};
就像其他人提到的那样,触发器处理程序可以自由地安排它们自己的回调函数,如果他们愿意的话。因此,无论处理程序是否在返回之前完成工作是取决于处理程序代码本身的。
根据源代码,触发器是同步的,但并不意味着所有监听“pre_render”事件的函数都会执行同步操作。
附注:源代码非常容易阅读,你应该真的看一下: