在异步函数调用过程中,当对象的属性值发生变化时,JavaScript中的对象属性值会发生什么变化
What happens to property values on an object in JavaScript when its property values change during asynchronous function calls?
我想知道传递给异步函数(如数据库保存)的javascript对象会发生什么,然后立即更改其属性值。
我对此感兴趣的原因是异步代码需要很长时间才能完成,因此等待它回调的时间将比我想要的响应时间更长。
取以下代码:
function asyncDatabaseSave(user) {
// Save the user asynchronously in the database
// Do things that take a lot of time before calling back
}
app.get(function (req, res) {
// In real code user is an object that gets passed in.
user = {cart: [1, 2, 3]};
// What is the value of user.cart going to be when it reaches the databaseSave call?
// At the time of the function call, user.cart has options but it is set to null immediately after
asyncDatabaseSave(user);
user.cart = null;
res.json(user);
})
我认为,确保用户对象是用cart而不是null
保存的,然后清除它的"正确"方法是将回调传递到asyncDatabaseSave
,在保存后将其设置为null
。
不过,我有兴趣尽快致电res.json
。我也试验过这个代码:
app.get(function (req, res) {
var items = user.cart;
user.cart = null;
res.json(user);
asyncDatabaseSave(user, items);
})
通过这种方式,items
被存储为一个单独的var,并被传递到一个稍微修改过的数据库保存函数中。
当调用asyncDatabaseSave
,然后立即将其设置为null
时,user.cart
会发生什么?
如果我试图用购物车保存user
,但也将购物车设置为null
的user
返回,那么最好的方法是什么?
当调用asyncDatabaseSave,然后它之后立即设置为null?
您必须知道异步数据库调用中实际发生了什么,才能知道在进行调用后立即修改传入的对象是否安全。在许多情况下,user
对象的操作部分已经被复制到本地代码中,并在asyncDatabaseSave()
返回之前发送到数据库,因此进一步修改user
对象根本不会影响异步调用。
但是,在某些情况下,你不能假设这一点,特别是如果asyncDatabaseSave()
实际上由几个异步调用组成,并且在它们之间运行一些Javascript(例如打开数据库,然后写入数据库。在这些情况下,修改你所在的user
对象可能会影响事情。
如果我试图用购物车保存用户,但也用返回用户cart设置为null,最好的方法是什么?
因此,为了安全起见,不要在asyncDatabaseSave(user)
之后立即修改user
对象。
如果您真的只是想尽快调用res.json(user)
,那么您只需制作user
对象的副本,修改该副本,然后在两个异步操作中使用每个单独的副本。这是在所有情况下都有效的一般答案,也是安全的做事方式。
如果asyncDatabaseSave()
中不需要整个cart
对象,那么只挑选需要的部分并传递这些部分(就像您上次的建议一样),就可以在之后自由分配cart
属性,而不会有任何风险。您必须小心不要访问cart
对象并更改cart
对象中的对象,因为这可能会更改您传递给asyncDatabaseSave()
的相同对象,但您当然可以为cart
对象分配属性,如果您不传递cart
对象,这不会影响asyncDatabaseSave()
。
这里有一个简单的例子来展示假设您可以修改传入的对象是如何不安全的:
function someAsyncSave(u) {
setTimeout(function() {
log(u.name)
}, 50);
}
var user = {name: "Joe"};
someAsyncSave(user);
user.name = "Alice";
<script src="http://files.the-friend-family.com/log.js"></script>
运行代码段。它将记录"Alice",即使调用someAsyncSave()
时属性为"Joe"。
尽管user
对象在传递给someAsyncSave()
时具有user.name = "Joe"
,但当someAsyncSave()
实际使用该属性时,它已经被外部代码更改。
- Javascript对象颜色动态变化
- Knockoutjs当父对象's可观察到的变化
- 在异步函数调用过程中,当对象的属性值发生变化时,JavaScript中的对象属性值会发生什么变化
- Javascript单元测试依赖关系-当依赖对象发生变化时,如何使测试失败
- AngularJS:如何在指令范围的对象发生变化时更新与控制器作用域相关联的控制器作用域
- 比较两个JSON对象以查看角度变化
- 计算JavaScript对象中属性百分比的变化
- Angular:当列表发生变化时,如何重新绑定到之前选择的对象
- 检测JS中CSSStyleDeclaration对象的变化
- 升级到jQuery 1.7和事件对象的变化
- Rxjs观察对象的更新和变化
- 为什么JavaScript参数对象会因赋值给参数而发生变化?
- addEventListener的变化,可以访问一个对象中的方法
- 为什么在调用对对象方法的引用时,方法的“this”会发生变化
- JavaScript修改对象原型来监控变化
- 继承对象的变化反映到父对象
- 如何观察对象方法返回的属性变化
- 可以'我不明白为什么我的对象中的值在变化
- 如果克隆的对象发生变化,则重新克隆对象
- 如何在服务中观察数组或对象的变化