下面是 Backbone 的 set 方法的片段:
set: function(key, val, options) {
var attr, attrs, unset, changes, silent, changing, prev, current;
...
options || (options = {});
...
// Trigger all relevant attribute changes.
if (!silent) {
if (changes.length) this._pending = options;
for (var i = 0, length = changes.length; i < length; i++) {
this.trigger('change:' + changes[i], this, current[changes[i]], options);
}
}
// You might be wondering why there's a `while` loop here. Changes can
// be recursively nested within `"change"` events.
if (changing) return this;
if (!silent) {
while (this._pending) {
options = this._pending;
this._pending = false;
this.trigger('change', this, options);
}
}
this._pending = false;
this._changing = false;
return this;
}
尽管评论确实提到了我想知道的 while
循环,但我看不出这个 while 循环是如何工作的,因为局部变量 changing
将始终是 true
在一轮 set
中。
谁能给我解释一下为什么会有一段时间,什么时候生效?
提前致谢!
最佳答案
正如评论所说,“更改可以递归地嵌套在 “change”
事件中。”
当 "change"
事件被触发时,也就是再次调用 set
时,更新或重新设置模型的某些属性并不是取消注释。 _pending
属性只是为了确保在 “更改”
上更新的所有属性实际上都已更改。
看起来他们曾经检查过是否有额外的变化,以及是否有 Backbone 用于发射 just 1 change event .这样做的问题是,如果有更新 多个 属性的更改事件的监听器,则不会调用所有 set
函数。参见 this unit test举个具体的例子。因此 while
循环处理 1 个监听器多次调用 set
的边缘情况,而不是多个监听器,每个监听器调用一次 set
。就像上面链接的测试中的这个:
model.on('change:a', function() {
model.set({b: true});
model.set({b: true});
});
如果您对为什么他们将 this._pending
更改为选项感到困惑,请查看 this issue & the associated pull request
关于javascript - 为什么Backbone的set方法中有一个while循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27630751/