【问题标题】:Relationnal model with Towerjs (coffeescript & mongodb)使用 Tower Js 的关系模型(coffeescript & mongodb)
【发布时间】:2012-05-30 05:30:13
【问题描述】:

我需要从一个用户的所有交易中的所有股票中恢复 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

【问题讨论】:

  • where 是异步的吗?
  • 从技术上讲,allfirst 是异步的,where 只是构建查询。

标签: node.js mongodb coffeescript connect towerjs


【解决方案1】:

看起来有几个地方可能会出现问题。

在第一个 while 循环中,我不确定您是否是这个意思:

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

最后一点,idst[trade.get('stockId')] 永远不会被设置。但这不会中断 while 循环,所以可能不是问题。

主要的是,因为第二个和第三个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

另外,如果我是你,我会将每个迭代器放入单独的函数中,或者使用不同的索引变量(例如ijk)。它使精神上更容易处理这种异步性质。

让我知道这是否有效。干杯。

【讨论】:

    【解决方案2】:

    哦,天哪,你的代码看起来很糟糕......(在嵌套范围内有很多 i++i &lt; length)请......不要这样写代码,闻起来太糟糕了。嵌套循环会导致您的代码难以阅读,尤其是存在影子变量。

    所以,你遇到的问题是“影子变量”,它看起来像:

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

    我建议你改进算法的实现,避免使用影子变量。

    【讨论】:

      猜你喜欢
      • 2018-07-04
      • 1970-01-01
      • 2013-01-09
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多