Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 观察同步回调_Javascript_Angularjs_Object.observe - Fatal编程技术网

Javascript 观察同步回调

Javascript 观察同步回调,javascript,angularjs,object.observe,Javascript,Angularjs,Object.observe,我一直在用ChromeV36的Object.observe做实验。我最初的意图是在我的模型中将其用于业务逻辑,但异步行为似乎使其不可能。我将此归结为以下示例: function Person(name) { this.name = name; this.someOtherProperty = null; this.watch = function() { var self = this; Object.observe(this, functi

我一直在用ChromeV36的Object.observe做实验。我最初的意图是在我的模型中将其用于业务逻辑,但异步行为似乎使其不可能。我将此归结为以下示例:

function Person(name) {
   this.name = name;
   this.someOtherProperty = null;

   this.watch = function()
   {
       var self = this;
       Object.observe(this, function(changes){
           for(var i = 0; i < changes.length; i++)
           {
               if(changes[i].name == "name")
               {
                   self.someOtherProperty = changes[i].newValue;
                   console.log("Property Changed");
               }
           }
       });
   }
}

$(function () {
    var p = new Person("Alice");
    p.watch();
    p.name = "Bob";
    $("#output").text("Output: "+ p.someOtherProperty);
    console.log("Output");
});
职能人员(姓名){
this.name=名称;
this.someOtherProperty=null;
this.watch=函数()
{
var self=这个;
对象。观察(此、功能(更改){
对于(变量i=0;i
链接,使用jQuery

我的问题是在“属性更改”之前调用“输出”。有没有什么方法可以使Object.observesynchronous,或者我应该用一种更好的方法?(我用的是AngularJS,顺便说一句)

这里的问题不是向DOM添加文本,也不是向控制台输出。当
name
发生更改时,我的业务逻辑要求我立即更新
someotherproperty
,我更喜欢将此逻辑封装在我的模型中


显然,这只是一个示例,但我有依赖于即时执行的业务规则。

对象。请注意,
,“很遗憾”(阅读下一页),不执行同步任务。一旦“微任务”结束,它就会发送更改通知

这是可以解释的

多年的web平台经验告诉我们,同步方法是您尝试的第一件事,因为它最容易让您绞尽脑汁。问题是,它创建了一个从根本上讲是危险的处理模型。如果你在写代码,比如说,更新一个对象的属性,你不会真的想要一个更新该对象属性的情况,可能会邀请一些任意代码去做它想做的事情。当你在函数中间运行时,让你的假设失效是不理想的

因此,调用
console.log(“Output”)
后,“微任务”结束,然后
Object.observe
通知对象上的更改

拥有同步事件的经典方法是使用getter和setter:

Person.prototype.setName = function(name) {
    this.name = name;
    console.log("Name Changed");
};

p.setName("Bob");

当然,这将迫使您为要查看的每个属性创建getter和setter,并忘记删除和添加新属性时发生的事件。

使用
对象是没有意义的。请同步观察
行为。它必须阻塞线程并等待某些内容发生更改

您应该将回调传递给
watch
函数,以便在发生更改时执行该函数:

this.watch = function (callback) {
    var self = this;
    Object.observe(this, function (changes) {
        changes.forEach(function (change) {
            if (change.name === 'name') {
                self.someOtherProperty = change.newValue;
                console.log("Property Changed");
                callback();
            }
        });
    });
}

$(function () {
    var p = new Person("Alice");
    p.watch(function () {
        // !!!!! OF COURCE YOU SHOULD NEVER DO IT LIKE THIS IN ANGULAR !!!! //
        $("#output").text("Output: " + p.someOtherProperty);
        console.log("Output");
    });
    p.name = "Bob";
});

顺便说一句,如果您使用的是Angular(通过您的代码和fiddle,这一点并不明显),那么您不应该关心在观察到的更改发生时执行任何代码。只要将代码包装在
$scope.$apply()
中,Angular就会负责更新视图等

例如:


输出:{p.someOtherProperty}
.controller('someCtrl',函数($scope,Person){
$scope.p=新人('Alice');
$scope.p.watch();
$scope.p.name='Bob';
});
应用程序工厂('Person',函数($rootScope){
返回功能人员(姓名){
var self=这个;
self.name=名称;
self.someOtherProperty=null;
this.watch=函数(){
观察对象(自身、功能(变化){
$rootScope.$apply(函数(){
更改。forEach(函数(更改){
控制台日志(更改);
如果(change.name=='name'){
self.someOtherProperty=self.name;
}
});
});
});
};
};
});

另请参见此


更好的是,请参见此
基本上,使用
O.O
而不是Angular的脏检查的优点是节省了
$$watchers
,因此
$digest
周期更快,成本更低。

Angular也会在ES6出现时使用此机制(
O.O
)。

正如您所说,observe是不同步的。但是你可以让watch回拨并在那里更新“someOtherProperty”。像这样

$(function () {
    var p = new Person("Alice");
    p.watch(function(){
        $("#output").text("Output: "+ p.someOtherProperty);
    });
    p.name = "Bob";
    console.log("Output");
});

你真正想要的是什么,我想你知道这是预期的行为。@ExpertSystem我想他的意思是,有时候,如果
O.O
是同步的,它会很有用。但这是一个经验问题,因为同步解决方案会导致许多其他潜在问题。这也是为什么我们使用了
MutationObserver
而不是
MutationEvents
@TroelsLarsen,MaxArt:我以为你在谈论
O.O
本身的(同步/异步)性质。似乎您正在讨论调用
O.O
侦听器回调的方法。所以,我们现在在同一页上,我同意这两个观点:)@ExpertSystem:好的,我想我现在明白你的意思了。我想克里斯汀森是对的。我需要以某种方式使用getter和setter。@TroelsLarsen:这取决于您试图对代码做什么。如果您只想更新视图,则不需要getter/setter(感谢Angular)。请看,我回答中的最后一个示例/演示。@ExpertSystem:回顾过去,我不应该以视图为例。这仅用于模型内的业务逻辑。因此,如果PropertyA发生变化,PropertyB将获得一个新值。我将angular抽象为angular,因为我(目前)在模型中不需要DependencyInjection。类似地,我不想知道任何关于角度范围或类似的东西。我不介意为ge编写(生成)代码
$(function () {
    var p = new Person("Alice");
    p.watch(function(){
        $("#output").text("Output: "+ p.someOtherProperty);
    });
    p.name = "Bob";
    console.log("Output");
});