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 段的结果,从对话中获取有关最新报告的一系列信息。[{mail_id:98,主题:测试,所有者:5757,查看者:5866,时间戳:123566544},{etc...}]
  3. 获取有关指定标识符的用户的信息 (owner_user_id/viewer_user_id)。
  4. 在同一个数组中收集所有对话数据。

我停在第三段。也就是说,我不知道如何始终如一地获取有关前两个数组中的用户的信息。

请帮帮我!

4

3 回答 3

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 的数组中的一个项目。这部分我相信你是对的。然而,第二个参数是一个回调,有两个参数。一个错误和一组结果。这是我认为你搞砸的部分。您应该调用此回调。在内部 async.map 提供了回调参数,这个回调参数是 async.map 将结果收集到数组中的方式。如果不调用 this,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);
    });
}
于 2013-07-16T14:42:43.997 回答
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);
      });
    });
于 2013-07-16T14:46:11.427 回答
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);
                 });                 
             });
          });
        });
    }

它奏效了!:)

屏幕 http://screencloud.net//img/screenshots/411f98a583916a41142c40294fd2ee00.png

但在我看来,这段代码 - 很烂!

于 2013-07-16T17:44:42.770 回答