0

1 人のユーザーのすべての取引のすべての株式から、towerjs (mongodb ストアを使用) の引用株式を回復する必要があります。このコードは機能しません。while ループは停止しませんが、理由がわかりません

    App.Trade.where(userId: @currentUser.get('id')).order("date", "desc").all (error, trades) ->
      idst = {}
      i = 0
      len = trades.length          

      while i < len
        trade = trades[i]
        idst[trade.get('stockTicker')] = 1  if trade.get('stockId') and not idst[trade.get('stockId')]
        i++

      App.Stock.where({ticker: {$in: Object.keys(idst)}}).all (error, stocks) ->
        map = {}
        mapQuote = {}
        i = 0
        len = stocks.length

        while i < len
          stock = stocks[i]
          map[stock.get('ticker')] = stock
          App.QuoteStock.where(ticker: stock.get('ticker')).order("createdAt", "desc").limit(1).first (error, quoteStock) ->
            mapQuote[stock.get('ticker')] = quoteStock
            i++

        i = 0
        len = trades.length
        while i < len
          trade = trades[i]
          trade.stock = map[trade.get('stockTicker')]
          trade.quoteStock = mapQuote[trade.get('stockTicker')]
          i++

        _this.trades = trades
4

2 に答える 2

2

問題が発生している可能性のある場所がいくつかあるようです。

最初のwhileループでは、あなたがこれを意味したかどうかはわかりません:

idst[trade.get('stockTicker')] = 1  if trade.get('stockId') and not idst[trade.get('stockId')]

その最後のビットidst[trade.get('stockId')]は、決して設定されません。しかし、それはwhileループを中断しないので、おそらく問題ではありません。

主なことは、2番目と3番目のwhileループが非同期App.Trade.where関数内にあるため、正しく機能しないということです。

また、非同期コードは反復ごとに呼び出されるため、以下は機能しません。

while i < len
  stock = stocks[i]
  map[stock.get('ticker')] = stock
  App.QuoteStock.where(ticker: stock.get('ticker')).order("createdAt", "desc").limit(1).first (error, quoteStock) ->
    mapQuote[stock.get('ticker')] = quoteStock
    i++

代わりに、非同期ループを使用する必要があります:https ://github.com/caolan/async 。あなたはこのようにそれを行うことができます:

async = require('async')

stocksIterator = (stock, next) ->
  map[stock.get('ticker')] = stock
  App.QuoteStock.where(ticker: stock.get('ticker')).order("createdAt", "desc").limit(1).first (error, quoteStock) ->
    mapQuote[stock.get('ticker')] = quoteStock
    next()

async.forEachSeries stocks, stocksIterator, (error) ->
  tradesIterator = (trade, next) ->
    trade.stock = map[trade.get('stockTicker')]
    trade.quoteStock = mapQuote[trade.get('stockTicker')]
    next()

  async.forEachSeries trades, tradesIterator, (error) ->
    _this.trades = trades

また、私があなたなら、これらのイテレータのそれぞれを別々の関数に入れるか、異なるインデックス変数(たとえば、)をi使用jします。kこれにより、この非同期性の精神的な対処が容易になります。

それがうまくいくかどうか教えてください。乾杯。

于 2012-05-24T04:29:36.470 に答える
1

なんてこった、あなたのコードはひどいように見えます...(ネストされたスコープに非常に多くのi++、、i < lengthが)お願いします...そのようにコードを書かないでください、あまりにも臭いです。ネストされたループはコードを読みにくくします。特にシャドウ変数があります。

したがって、遭遇した問題は「シャドウ変数」であり、次のようになります。

some_var = "I am normal"
shadow_it = -> 
  some_var = "this is the shadow"
  # blabla

アルゴリズムの実装を改善し、シャドウ変数の使用を避けることをお勧めします。

于 2012-05-24T06:22:15.297 に答える