0

我想用角度构建一个承诺链来应用一组查询:

           for(variableIndex in _editableVariable.values) {
                var v = _editableVariable.values[variableIndex];
                if(v.value != v.old_value) {
                    console.log('v', v);
                    var newVariableRes = new VariableValueRes(v);
                    if(v.old_value == undefined) {
                        p.then(function() {
                            console.log('B', newVariableRes);
                            return newVariableRes.$save().$promise;
                        });
                    } else {
                        console.log('Try update: ', v);
                        p.then(function() {
                            console.log('C', newVariableRes);
                            return newVariableRes.$update().$promise;
                        });
                    }
                }
            }

我的问题是当我显示不同的变量时console.log('v',v)我得到了不同value的结果。当我在承诺中并显示最新变量console.log('B', newVariableRes)的内容newVariableResvalue

输出示例:

v 
Object {value: "1", old_value: undefined, platform: "/api/v1/platform/1", product_variable: "/api/v1/product_var/2"}
v 
Object {value: "2", old_value: undefined, platform: "/api/v1/platform/2", product_variable: "/api/v1/product_var/2"}
v 
Object {value: "3", old_value: "", id: 7, platform: "/api/v1/platform/3", product_variable: "/api/v1/product_var/2"}

B 
Resource {value: "3", old_value: "", id: 7, platform: "/api/v1/platform/3", product_variable: "/api/v1/product_var/2"…}
B 
Resource {value: "3", old_value: "", id: 7, platform: "/api/v1/platform/3", product_variable: "/api/v1/product_var/2"…}
C 
Resource {value: "3", old_value: "", id: 7, platform: "/api/v1/platform/3", product_variable: "/api/v1/product_var/2"…}

由于我是 javascript 新手,我认为这v是对价值的参考。因此VariableValueRes采用此参考。当我更改 的指向引用时v,这不应该更改VariableValueRes.

我的误解在哪里?

4

1 回答 1

1

我认为问题在于 JS 只有全局或函数范围。因此,您的vnewVariableRes变量(在您的 for 循环中声明)被视为与它们被声明为周围函数的顶部相同。

循环的每次迭代, 的值v都会立即更新和记录,显示您希望看到的值。然而,当你的 Promise 回调执行时,循环已经完成,v并且newVariableRes会保存最后一个放入其中的值。

这些回调newVariableRes通过闭包引用,这意味着外部函数可以完成并且内部函数(您的回调)仍然使用外部作用域中此变量的值,而不是使用创建函数时存在的任何值。

这是在 JS 代码中看到的一个非常常见的错误,通常解决方案是通过将变量放入新的函数范围来修复变量,如下所示

p.then((function(nvr) {
    return function() {
        console.log('B', nvr);
        return nvr.$save().$promise;
    };
})(newVariableRes));

通过这种方式,我们创建了一个函数,将我们的变量作为参数提供给它。由于我们不会在函数中更改此参数,因此我们的回调可以通过闭包使用它并确保它不会更改。

一种更简单的方法是,因为您已经在使用 angular,所以用 for 替换您的循环,angular.forEach它将以与 for 完全相同的方式解决此问题v。现在您知道v了您最初在回调中所期望的内容,您可以new VariableValueRes(v)在这些回调中创建,而不必担心newVariableRes指向什么(因为您不会使用它)。

于 2013-11-03T14:51:36.797 回答