asynchronous编程如何影响对象的属性

我有一个用户对象,看起来像这样:

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

这个对象被发布到我的express.js web应用程序。 在特定的路由上,很多中间件作用于该对象,并且还被发回给用户。

问题是一些在用户上操作的中间件是asynchronous的,并且修改了用户对象。 此外,我尝试尽快发回用户对象的响应。

鉴于Javascript使用共享呼叫,我不知道该对象会发生什么,因为它的属性被asynchronous函数(可能在对象被发回之前)修改。 这是我正在谈论的。

 // 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 ,它需要用户完整的,未修改的cart属性。 但是,为了尽快发回服务器的响应(因为user.cart将始终是一个空数组),我将user.cart设置为一个空数组,并立即将其发回。

如果JS做了一个对象的副本,我不用担心,但它不,所以我不知道什么时候user.cart的价值是什么,当涉及到asyncSaveCartInDataBase的callback。

有没有一种方法来使用JS和节点的asynchronous性质来更改user.cart属性,并立即发回,而不修改它在asynchronous函数中使用的属性。 我需要做一个很深的克隆吗?

你在做什么听起来有点噩梦。 你有不同的中间件在同一个对象上运行。 有些人正在改变它,有些则不然,有些则不合时宜。

在我看来,你必须更明确地分开你的关注点。 好像有两种中间件你正在使用:

  1. 将请求转换为响应的中间件发回给用户
  2. 需要原始请求的中间件(或其一些变体)

我的build议是这样的:

  1. 确保有一个由中间件转换的请求实例。
  2. 任何需要自己的,未经修改的请求变体的中间件都必须对其需要的全部或部分请求进行深层复制。

JavaScript是asynchronous和单线程的,但这并不意味着它不受竞争条件的限制。 共享状态仍然会导致问题,应该尽可能地减less。