简体   繁体   中英

map() in node.js, async vs sync?

I have a segment code like below running in Node.js. And I find it will always goes to else condiction, howerver with masterData is not null.

getOperationDetails(req, res) {
   let sql = 'select a.*, b.s*';
       sql += ` from ${paymentSheet} a left join ${paymentHisSheet} b on a.id= b.source_id `;
       sql += ' where a.id=? ';
   func.connPool(sql, id, (err, rows, field) => {
       if (err) {
         res.json({ code: 400, message: err })
       } else {
         let masterData = [];
         let details = rows.map((row, idx) => {
          if (idx === 0) {
            masterData.push({
              id: row.id,
              name: row.name
            });
          }
          return {
            operator: row.operator_info,
            comments: row.cmt,
            status: row.sta
          }
         })
        if (masterData.length > 0 ) { 
          masterData[0].details = details;
        } else {
          console.log(sql);
          console.log(id);
          console.log('=======================');
          console.log(masterData);
        }
        res.json({ code: 200, message: 'ok', data: masterData })
      }
   })

For example, the console will show like below. Obviously masterData has value. It means 'if' condiction run before map(). Do I have to use async to wait the map() handle the data over?

allConnections:2
select a.*, b.* from payment a left join history b on a.id= b.source_id  where a.id=? 
83e588cd-9b4b-4592-ac7f-529bfaa9b231
=======================
allConnections:2
allConnections:2
[
   {
     id: '83e588cd-9b4b-4592-ac7f-529bfaa9b231',
     name: 'Jeff'
    }
 ]

My anaysis:

the rows from database should like below

83e588cd-9b4b-4592-ac7f-529bfaa9b231', 'Jeff', 'Operator Peter', 'OK', 0
83e588cd-9b4b-4592-ac7f-529bfaa9b231', 'Jeff', 'Operator Mary', 'NO', 1
83e588cd-9b4b-4592-ac7f-529bfaa9b231', 'Jeff', 'Operator Jet', 'OK', 2

or like below, means no details

83e588cd-9b4b-4592-ac7f-529bfaa9b231', 'Jeff', null, null, null

That is why I use masterData to separate. I think push() should not be taken out the map(), becasue rows maybe return nothing. Will it be like map() is over and push() is still running?

==== PS func.connPool====

let mysql = require('mysql');
let db = require('../configs/db');
let pool = mysql.createPool(db);

module.exports = {
  connPool (sql, val, cb) {
      pool.getConnection((err, conn) => {
        if (err) {
          console.log('Connection Error:' + err);
          cb(err, null, null);
        } else {
          console.log('allConnections:' + pool._allConnections.length);
          let q = conn.query(sql, val, (err, rows,fields) => {
          pool.releaseConnection(conn);
          if (err) {
            console.log('Query:' + sql + ' error:' + err);
          }
          cb(err, rows, fields);
        });
      }
    });
  },

What I suspected is that the push operation is somehow delay because of some code that is not shown here (I am not certain yet).

I ran the following code so many times, I still could not reproduce your problem.

var rows = [
    {
        id: "123",
        name: "test",
    },
    {
        id: "123",
        name: "test",
    },
    {
        id: "123",
        name: "test",
    },
]

let masterData = [];
let details = rows.map((row, idx) => {
    if (idx === 0) {
      masterData.push({
        id: row.id,
        name: row.name
      });
    }
    return {
      id: row.id,
      name: row.name,
    }
})
if (masterData.length > 0 ) {
    console.log("in");
} else {
    console.log(masterData);
    console.log('=======================');
}

Could you try whether it goes to else or not for this code.

From this piece of code you are pushing to MasterData only the first row.id and row.name.

( that is specified in the if conditional for just the first index idx === 0 )

So if thats the case you don't need to have this push thing inside the map.

You can take that out of the map and leave the iterator to create only the details array.

You can go with:

 let details = rows.map(row => ({
     operator: row.operator_info,
     comments: row.cmt,
     status: row.sta
     })
  );


let masterData = [{ id: rows[0].id, name: rows[0].name, details }]


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM