2016-12-22 6 views
1

私はこのようになり、ユーザーオブジェクトを持っている:どのように非同期プログラミングは、オブジェクトのプロパティに影響を与えない

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

このオブジェクトは、私のexpress.jsウェブアプリに掲載されています。特定のルートでは、多くのミドルウェアがそのオブジェクトに作用し、ユーザーにも返されます。

問題は、ユーザー上で動作するミドルウェアの一部が非同期で、ユーザーオブジェクトを変更することです。また、私はできるだけ早く応答でユーザーオブジェクトを送り返そうとします。

JavaScriptが共有によるコールを使用しているとすれば、(オブジェクトが返される前に)非同期関数によってそのプロパティが変更されているため、オブジェクトに何が起こるかわかりません。ここに私が話していることがあります。ここで

// 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); 
}); 

asyncSaveCartInDataBaseuserの完全な、無修正カートのプロパティを必要とする、と呼ばれています。しかし、サーバーからの応答をできるだけ早く返信しようと努力しています(そして最後にuser.cartが空の配列になるため)私はuser.cartを空の配列に設定して直ちにそれを送り返します。

JSがオブジェクトのコピーを作成した場合、私は心配する必要はありませんが、user.cartの値がasyncSaveCartInDataBaseの場合はどういう値なのか分かりません。

JSとノードの非同期性を利用してuser.cartプロパティを変更し、すぐに非同期関数で使用するためのプロパティを変更しないでそれを送り返す方法はありますか?私は深いクローンや何かを作らなければなりませんか?

+0

オブジェクトをコピーする必要があります。 – SLaks

+0

単に 'user'のコピーを作成して空の配列で送信するのはなぜですか? – Mike

+0

最適化は、 'user.cart'のバックアップを作成し、応答を登録し、カートをユーザに復元することです。 – Amadan

答えて

4

あなたがしていることは、少し悪夢のように聞こえる。同じミドルウェアが同じオブジェクト上で動作しています。一部は変異しており、一部は変異しておらず、一部は順不同である。

私はあなたの懸念をもう少し明示的に分けなければならないようです。使用しているミドルウェアの2種類があるように思える:

  1. 元の要求(またはその一部の変異体)を必要とするユーザー
  2. ミドルウェアに送り返されるレスポンスにリクエストを変換ミドルウェア

私の推薦はこれです:

  1. ミドルウェアによって変換されます要求の単一のインスタンスがあることを確認してください。
  2. 要求の独自の変更を必要とするミドルウェアは、要求の全部または一部を詳細にコピーする必要があります。

JavaScriptは非同期でシングルスレッドですが、それは競合状態から免れるわけではありません。共有状態でも問題が発生するため、可能な限り最小限に抑える必要があります。

関連する問題