4 javascript ecmascript-harmony object.observe
我想了解Object.getNotifier(object).performChange.从概念上讲,我理解它是为定义"宏"或更高级别的更改而设计的.从示例中,每个人似乎都参考:
increment: function(amount) {
var notifier = Object.getNotifier(this);
notifier.performChange(Thingy.INCREMENT, function() {
this.a += amount;
this.b += amount;
}, this);
notifier.notify({
object: this,
type: Thingy.INCREMENT,
incremented: amount
});
}
Run Code Online (Sandbox Code Playgroud)
我不明白的是,这与简单地执行notifier.performChange直接传递的匿名函数有什么不同,而不是作为回调?换句话说,它与以下内容有何不同:
increment: function(amount) {
var notifier = Object.getNotifier(this);
this.a += amount;
this.b += amount;
notifier.notify({
object: this,
type: Thingy.INCREMENT,
incremented: amount
});
}
Run Code Online (Sandbox Code Playgroud)
我已经看到,在最新的规范中,notifier.performChange可能会返回一个对象,然后将其作为通知发布,如:
notifier.performChange(Thing.INCREMENT, function() {
this.a += amount;
this.b += amount;
// a notification is issues with this return value,
// including the type passed to notifier.performChange,
// and the object underlying notifier.
return {incremented: amount};
});
Run Code Online (Sandbox Code Playgroud)
这消除了notifier.notify原始代码中对以下内容的需求,但是,这仍然是除了糖之外的其他东西,或者它之间是否存在功能差异,只是自己进行更改并发出通知?
我想为这个问题提供一个明确的答案,我也问自己,所以我看了一下Object.observe规范.
以下是您需要了解的内容Object.getNotifier(obj).performChange(changeType, changeFn):
changeFnchangeFn运行时,它故意不通知任何观察者可能发生的变化objchangeFn返回一个对象:obj将通过该对象自己的属性通知观察者为了亲眼看看,这%NotifierPrototype%.performChange(changeType, changeFn)是你在规范中寻找的东西.
应用于您的示例,这意味着这两个导致完全相同的结果,而做一些不同的事情:
例1:
increment: function(amount) {
var notifier = Object.getNotifier(this);
notifier.performChange(Thingy.INCREMENT, function() {
this.a += amount;
this.b += amount;
});
notifier.notify({
object: this,
type: Thingy.INCREMENT,
incremented: amount
});
}
Run Code Online (Sandbox Code Playgroud)
在第一个例子中:
performChange()行为,回调函数内对象属性的更改将保持静默undefined,performChange()不会通知任何观察者任何其他内容notify()明确通知相应的观察者传递的更改记录例2:
increment: function(amount) {
var notifier = Object.getNotifier(this);
notifier.performChange(Thingy.INCREMENT, function() {
this.a += amount;
this.b += amount;
return { incremented: amount };
});
}
Run Code Online (Sandbox Code Playgroud)
在第二个例子中:
performChange()行为,回调函数内对象属性的更改将保持静默performChange()将通过一个看起来与notify()示例1中显式调用得到的对象相同的对象通知相应的观察者:{ object: Object, type: Thingy.INCREMENT, increment: amount }这两个示例应涵盖您想要使用的大多数情况performChange(),以及如何使用它.我会继续潜水,因为这种野兽的行为非常有趣.
观察者是异步执行的.这意味着,一切内部发生的increment()功能在上面实际上是报告给观察者的例子中,一旦increment()完成执行 -也只有那时.
换句话说,所有这些:
performChange()performChange()回调中返回一个对象notify()只有在increment()完成运行后才会通知相应的观察者.
如果您需要了解increment()执行期间的挂起更改(挂起的更改=将在结束时报告给观察者increment()但尚未报告的所有更改),则有一个解决方案:Object.deliverChangeRecords(callback).
请注意,虽然这callback需要是对您之前已注册为该对象的观察回调的函数的引用.
换句话说,这不起作用:
(function() {
var obj = { prop: "a" };
Object.observe(obj, function(changes) {
console.log(changes);
});
obj.prop = "b";
Object.deliverChangeRecords(function(changes) {
console.log(changes);
});
console.log("End of execution");
})(); // Meh, we're notified of changes here, which isn't what we wantedRun Code Online (Sandbox Code Playgroud)
虽然这会:
(function() {
var obj = { prop: "a" },
callback = function(changes) {
console.log(changes);
};
Object.observe(obj, callback)
obj.prop = "b";
Object.deliverChangeRecords(callback); // Notified of changes here, synchronously: yay!
console.log("End of execution");
})();Run Code Online (Sandbox Code Playgroud)
原因是在内部,调用Object.observe(obj, callback)一个对象obj会将传递的callback函数添加到obj观察回调列表中([[ChangeObservers]]在规范中称为).这些回调中的每一个都只会针对特定类型的更改(第三个Object.observe()参数)执行,如果没有传递参数,则会执行所有默认值.(这是一个重要的细节,因为这意味着如果你想使用自定义type的更改,你需要明确地将它传递给Object.observe()第三个参数,否则你不会收到有关该类型的任何更改的通知.)
此外,每个挂起的更改都将在内部添加到每个匹配的观察回调队列中.这意味着每个观察回调都有自己的待定更改集.
而这正是Object.deliverChangeRecords(callback)它的用途:它callback通过传递所有这些更改来获取所有挂起的更改并执行该回调.
这就解释了为什么deliverChangeRecords()只需要一个参数,即回调的参数.如下面的示例所示,传递回调deliverChangeRecords()将执行该回调及其所有挂起的更改,包括来自多个对象的更改.这与回调的一般行为一致,可能是异步调用或通过调用deliverChangeRecords().
(function() {
var obj1 = { prop1: "a" },
obj2 = { prop2: "a" },
commonCallback = function(changes) {
console.log(changes);
};
Object.observe(obj1, commonCallback);
Object.observe(obj2, commonCallback);
obj1.prop1 = "b";
obj2.prop2 = "b";
Object.deliverChangeRecords(commonCallback); // Notified of the changes to both obj1.prop1 and obj2.prop2
})();Run Code Online (Sandbox Code Playgroud)
此外,规范中提供了很多 用法示例.
| 归档时间: |
|
| 查看次数: |
367 次 |
| 最近记录: |