异步编程如何影响对象的属性

时间:2016-12-22 02:56:57

标签: javascript node.js asynchronous

我有一个如下所示的用户对象:

{
   name: "john",
   cart: [1, 2, 3]
}

此对象发布到我的express.js网络应用程序。在某些路由上,许多中间件作用于该对象,并且还将其发送回用户。

问题在于,对用户进行操作的某些中间件是异步的并修改了用户对象。此外,我尝试尽快将响应中的用户对象发回。

鉴于Javascript使用call-by-sharing,我不确定该对象会发生什么,因为它的属性被异步函数修改(可能在对象被发回之前)。这就是我所说的。

// This would be called after a post request
app.use(function (req, res, user) {
    asyncSaveCartInDataBase(user, function (user) {
       // Just an example
       user.cart.push('things')
    })
    user.cart = []
    res.json(user);
});

此处调用asyncSaveCartInDataBase,需要user的完整,未修改的购物车属性。但是,为了尽快从我的服务器发回响应(并且因为user.cart在结尾总是一个空数组)我将user.cart设置为空数组并立即发送它回来。

如果JS制作了该对象的副本,我不必担心,但事实并非如此,所以我不知道user.cart在{{1}的回调方面的价值是什么}。

有没有办法使用JS和节点的异步性质来更改asyncSaveCartInDataBase属性并立即将其发回,而不修改属性,以便在异步函数中使用它。我是否需要进行深层克隆或其他什么?

1 个答案:

答案 0 :(得分:4)

你在做什么听起来像是一场噩梦。您有不同的中间件在同一对象上运行。有些人正在改变它,有些则没有,有些则无序。

在我看来,你必须更明确地区分你的顾虑。您似乎使用了两种中间件:

  1. 将请求转换为发送回用户的响应的中间件
  2. 需要原始请求(或其某些变体)的中间件
  3. 我的建议如下:

    1. 确保由中间件转换的请求的单个实例。
    2. 任何需要其未经修改的请求变体的中间件必须对其所需的全部或部分请求进行深层复制。
    3. JavaScript是异步和单线程的,但这并不意味着它不受竞争条件的影响。共享状态仍会导致问题,应尽可能减少。