2013-07-16 135 views
0

使用node.js時出現問題。所有人都試圖在代碼的評論中描述。數據庫查詢中的異步

我需要用對話框和最後一個meggase的一些信息構建一個對話框數組的第一件事。

IM = { 
    iUserId: false, 
    socket: false, 
    checkDialog: function(socket) { 
     this.socket = socket; 
     // Returned [{owner: 123, viewer: 432}] 
     var sql = 'SELECT DISTINCT(`owner_user_id`), `viewer_user_id` FROM `phpfox_mail` WHERE `owner_user_id` = ' + this.iUserId + ' GROUP BY 1,2 UNION SELECT DISTINCT (`viewer_user_id`), `owner_user_id` FROM `phpfox_mail` WHERE `viewer_user_id` = ' + this.iUserId + ' GROUP BY 1,2 ORDER BY 1 '; 

     connection.query(sql, function(err, rows) { 
      if (err) throw err; 

      async.map(rows, function(item, nextParent) { 
       var sql = 'SELECT `mail_id`, `subject`, `preview`, `owner_user_id`, `viewer_user_id`, `viewer_is_new`, `time_stamp` FROM `phpfox_mail` WHERE (`viewer_user_id` = ' + item.viewer_user_id + ' OR `owner_user_id` = ' + item.viewer_user_id + ') AND (`viewer_user_id` = ' + item.owner_user_id + ' OR `owner_user_id` = ' + item.owner_user_id + ') ORDER BY `mail_id` DESC LIMIT 1'; 
       var dialogs = []; 
       connection.query(sql, function(err, rows) { 
       // ??? 
       }); 

      }, function(err, item) { 
       // Here I have to get the generated array with all the necessary dialogue. 
       console.log(item); 

       IM.socket.emit('logger', {text: 'dataIsABuilding', key: 'success'}); 
       IM.socket.emit('dialogsBuilding', item); 
      }); 
     }); 
    } 
}; 

目的:要創建的關於該消息的和對話者信息的數組。

方案:

  1. 獲取所有對話者的數組。 [{owner_user_id:5757,viewer_user_id:5866},{etc ...}]
  2. 使用第1段的結果,從對話中獲取最新報告的信息數組。獲取有關指定標識符(owner_user_id/viewer_user_id)的用戶信息。[{mail_id:98,subject:test,owner:5757,viewer:5866,timestamp:123566544},{etc ...}]
  3. 收集同一陣列中對話的所有數據。

我停在第三段。也就是說,我不知道如何持續獲得前兩個陣列中用戶的信息。

請幫助我!

+3

愛的帖子沒有直接的問題和大量的評論代碼排序通過...忽略諷刺,這將有助於,如果你要清理這個,很多,並用問號結束你的一個句子,最好一個包含某種查詢的新句子。在代碼評論中提出問題很簡單,並且讓代碼突出顯示幫助我們閱讀它!更不用說,我不確定評論代碼是否是問題的一部分,您的意圖是修復問題的一部分,還是在您從機器上覆制粘貼後忘記刪除它。 – ChrisCM

+0

@ChrisCM明白了。現在修復它。 – RomanGorbatko

+0

仍然有很大一部分註釋代碼...至少請修剪代碼(包括註釋和未註釋)到您試圖在您的機器上運行的最小一組內容,這些內容展示了您描述的問題。 – ChrisCM

回答

0

是的! :)

IM = { 
    iUserId: false, 
    socket: false, 
    checkDialog: function(socket) { 
     this.socket = socket; 
     var sql = 'SELECT DISTINCT(`owner_user_id`), `viewer_user_id` FROM `phpfox_mail` WHERE `owner_user_id` = ' + this.iUserId + ' GROUP BY 1,2 UNION SELECT DISTINCT (`viewer_user_id`), `owner_user_id` FROM `phpfox_mail` WHERE `viewer_user_id` = ' + this.iUserId + ' GROUP BY 1,2 ORDER BY 1 '; 
     connection.query(sql, function(err, rows) { 
      if (err) throw err; 

      async.map(rows, function(item, nextParent) { 
       var sql = 'SELECT `mail_id`, `subject`, `preview`, `owner_user_id`, `viewer_user_id`, `viewer_is_new`, `time_stamp` FROM `phpfox_mail` WHERE (`viewer_user_id` = ' + item.viewer_user_id + ' OR `owner_user_id` = ' + item.viewer_user_id + ') AND (`viewer_user_id` = ' + item.owner_user_id + ' OR `owner_user_id` = ' + item.owner_user_id + ') ORDER BY `mail_id` DESC LIMIT 1;'; 
       var dialogs = []; 
      connection.query(sql, function(err, rows) { 
       if(err) return nextParent(err); 
       nextParent(null, rows[0]); 
      }); 

      }, function(err, item) {    
      async.map(item, function(dialog, next) { 
       connection.query('SELECT `user_name`, `full_name`, `user_profile_image` FROM `phpfox_user` WHERE `user_id` = ' + dialog.owner_user_id, function(err, user) { 
        next(err, {owner: user[0], dialog: dialog}); 
       }); 
      }, function(err, rows) {     
       async.map(rows, function(dialog, next) { 
        connection.query('SELECT `user_name`, `full_name`, `user_profile_image` FROM `phpfox_user` WHERE `user_id` = ' + dialog['dialog']['viewer_user_id'], function(err, user) { 
         next(err, {viewer: user[0], dialog: dialog['dialog'], owner: dialog['owner']}); 
        }); 
       }, function(err, dialogs) { 
        console.log(dialogs); 
        IM.socket.emit('logger', {text: 'dataIsABuilding', key: 'success'}); 
        IM.socket.emit('dialogsBuilding', dialogs); 
       });     
      }); 
      }); 
     }); 
    } 

它的工作! :)

Screen http://screencloud.net//img/screenshots/411f98a583916a41142c40294fd2ee00.png

但在我看來,這個代碼 - 它吮吸!

1

我不相信你正在使用async.map函數。不幸的是,您正在使用它如此不正確,以至於我無法確定它實際上是在做什麼。但是,這裏是對你如何濫用的解釋,以及正確使用async.map函數。從異步文件

例子:

async.map(['file1','file2','file3'], fs.stat, function(err, results){ 
    // results is now an array of stats for each file 
}); 

讓我們簡化這一點。

async.map(someArray, someFunction, someCallBack); 

我相信你的問題在於someFunction參數。這是你的這個版本:

function(item, nextParent) { 
    var sql = 'SELECT `mail_id`, `subject`, `preview`, `owner_user_id`, `viewer_user_id`, `viewer_is_new`, `time_stamp` FROM `phpfox_mail` WHERE (`viewer_user_id` = ' + item.viewer_user_id + ' OR `owner_user_id` = ' + item.viewer_user_id + ') AND (`viewer_user_id` = ' + item.owner_user_id + ' OR `owner_user_id` = ' + item.owner_user_id + ') ORDER BY `mail_id` DESC LIMIT 1'; 
    var dialogs = []; 
    connection.query(sql, function(err, rows) { 
     // ??? 
    }); 
} 

此參數的功能,如果我們諮詢fs.Stat例子,應該用兩個參數,這首先是從我們送入async.map數組的項目。這部分我相信你是對的。 HOwever,第二個參數是一個回調,有兩個參數。一個錯誤和一組結果。這是我認爲你搞砸了的部分。你應該調用這個回調函數。內部async.map提供了回調參數,這個回調參數是async.map如何將結果收集到數組中的。如果沒有對此的調用,async.map無法收集結果。

我相信你想要的東西是這樣的:

function(item, someCallBackArgument) { 
    var sql = 'SELECT `mail_id`, `subject`, `preview`, `owner_user_id`, `viewer_user_id`, `viewer_is_new`, `time_stamp` FROM `phpfox_mail` WHERE (`viewer_user_id` = ' + item.viewer_user_id + ' OR `owner_user_id` = ' + item.viewer_user_id + ') AND (`viewer_user_id` = ' + item.owner_user_id + ' OR `owner_user_id` = ' + item.owner_user_id + ') ORDER BY `mail_id` DESC LIMIT 1'; 
    var dialogs = []; 
    connection.query(sql, function(err, rows) { 
     someCallBackArgument(err, rows); 
    }); 
} 
1

我假設這是一個關於如何使用async.map問題: 我已經重寫代碼,以便它使用回調正確: 你將需要調整輸出,但是這應該會返回一個包含所有需要的數據的數組。

connection.query(sql, function(err, rows) { 
     if (err) throw err; 

     async.map(rows, function(item, callback) { 
      var sql = 'SELECT `mail_id`, `subject`, `preview`, `owner_user_id`, `viewer_user_id`, `viewer_is_new`, `time_stamp` FROM `phpfox_mail` WHERE (`viewer_user_id` = ' + item.viewer_user_id + ' OR `owner_user_id` = ' + item.viewer_user_id + ') AND (`viewer_user_id` = ' + item.owner_user_id + ' OR `owner_user_id` = ' + item.owner_user_id + ') ORDER BY `mail_id` DESC LIMIT 1'; 
      var dialogs = []; 
      connection.query(sql, function(err, rows) { 
      if(err) return callback(err); 
      callback(null, { item: item, rows: rows}); 
      }); 

     }, function(err, item) { 
      // Here I have to get the generated array with all the necessary dialogue. 
      console.log(JSON.stringify(item)); 

      IM.socket.emit('logger', {text: 'dataIsABuilding', key: 'success'}); 
      IM.socket.emit('dialogsBuilding', item); 
     }); 
    }); 
+0

你的答案最接近目標。當我得到一個回調對象,該對象存儲關於對話和標識符對話者的信息。 '{item:{owner_user_id:37251,viewer_user_id:1}, rows: [{mail_id:3123, subject:'You received a infraction。',etc ...'但我需要獲得「項目」的值中描述了身份。 – RomanGorbatko

+0

大聲笑,它在邏輯上與我的相同...「最接近目標」......這很有趣。在這種情況下,您的查詢可能會混亂一點,請仔細檢查您的查詢是否正確。另外,變量行在同一範圍內被重新定義爲40次......至少這看起來很糟糕,並且將它與異步結合起來可能會讓事情變得很奇怪。 – ChrisCM

+1

我開始寫我的答案了! :) 我會推薦將有害函數分解爲命名函數來清理代碼並提供清晰度。 (這也會對性能有所幫助) – AndyD