【问题标题】:Why is my code not waiting for the completion of the function?为什么我的代码不等待函数完成?
【发布时间】:2018-08-01 23:45:21
【问题描述】:

我正在尝试从文件中读取一些数据并将其存储在数据库中。 这是更大交易的一部分,我需要返回的 ID 以进行进一步的步骤。

async parseHeaders(mysqlCon, ghID, csv) {
    var self = this;
    var hIDs = [];            
    var skip = true;
    var idx = 0;
    console.log("Parsing headers");
    return new Promise(async function(resolve, reject) {
        try {
            var lineReader = require('readline').createInterface({
                input: require('fs').createReadStream(csv)
            });
            await lineReader.on('close', async function () {
                console.log("done: ", JSON.stringify(hIDs));
                resolve(hIDs);
            });        
            await lineReader.on('line',  async function (line) {
                line = line.replace(/\"/g, '');
                if (line.startsWith("Variable")) {       //Variable,Statistics,Category,Control
                    console.log("found variables");
                    skip = false;                       //Ignore all data and skip to the parameter description.
                    return;                             //Skip also the header line.
                }
                if (!skip) {
                    var data = line.split(",");
                    if (data.length < 2) {                //Variable section done return results.
                        console.log("Found sub?",line);
                        return lineReader.close();
                    }
                    var v = data[0];
                    var bidx = data[0].indexOf(" [");
                    if (bidx > 0)
                        v = data[0].substring(0, bidx);  //[] are disturbing mysql (E.g.; Air temperature [�C])
                    var c = data[2];
                    hIDs[idx++] = await self.getParamID(mysqlCon, ghID, v, c, data);//, function(hID,sidx) {     //add data in case the parameter is not in DB, yet.
                }
            });
        } catch(e) {
            console.log(JSON.stringify(e));
            reject("some error occured: " + e);
        }            
    });
}

async getParamID(mysqlCon,ghID,variable,category,data) {
    return new Promise(function(resolve, reject) {
        var sql = "SELECT ID FROM Parameter WHERE GreenHouseID="+ghID+" AND Variable = '" + variable + "' AND Category='" + category + "'";
        mysqlCon.query(sql, function (err, result, fields) {
            if(result.length === 0 || err) {        //apparently not in DB, yet ... add it (Acronym and Machine need to be set manually).
                sql = "INSERT INTO Parameter (GreenHouseID,Variable,Category,Control) VALUES ("+ghID+",'"+variable+"','"+category+"','"+data[3]+"')";
                mysqlCon.query(sql, function (err, result) {
                    if(err) {
                        console.log(result,err,this.sql);
                        reject(err);
                    } else {
                        console.log("Inserting ",variable," into DB: ",JSON.stringify(result));
                        resolve(result.insertId);  //added, return generated ID.
                    }
                });
            } else {
                resolve(result[0].ID);         //found in DB .. return ID.     
            }
        });             
    });  
}

上述函数在基类中,由以下代码调用:

let headerIDs = await self.parseHeaders(mysqlCon, ghID, filePath); 
console.log("headers:",JSON.stringify(headerIDs));

事件的顺序是parseHeaders 中的所有内容都完成了,除了对self.getParamID 的调用,并且控制返回到调用函数,该函数为headerIDs 打印一个空数组。 然后会打印self.getParamID 中的console.log 语句。

我错过了什么? 谢谢

【问题讨论】:

  • 由于你使用的是async await,不需要使用新的promise,promise的内部函数会按照你的预期等待,但是你面临的问题是返回新的Promise
  • 请删除return new Promise(async function(resolve, reject) {,只删除return 而不是解析。
  • 此外,由于您使用的是 async await ,因此不需要回调函数,我的意思是await lineReader.on('close'); console.log(hIDs) return hIDS;
  • 做到了。现在 lineReader.on('close'... 没有等待。
  • @jallmer 请看上面的评论

标签: javascript node.js async-await es6-promise


【解决方案1】:

当您想为每一行执行异步操作时,我们可以定义一个处理程序来正确执行此操作:

 const once = (target, evt) => new Promise(res => target.on(evt, res));

 function mapLines(reader, action) {
   const results = [];
   let index = 0;
   reader.on("line", line => results.push(action(line, index++)));
   return once(reader, "close").then(() => Promise.all(results));
}

所以现在你可以轻松解决这个问题了:

  let skip = false;
  const hIDs = [];
   await  mapLines(lineReader, async function (line, idx) {
       line = line.replace(/\"/g, '');
       if (line.startsWith("Variable")) {       //Variable,Statistics,Category,Control
          console.log("found variables");
          skip = false;                       //Ignore all data and skip to the parameter description.
         return;                             //Skip also the header line.
     }
     if (!skip) {
         var data = line.split(",");
         if (data.length < 2) {                //Variable section done return results.
              console.log("Found sub?",line);
              return lineReader.close();
         }
         var v = data[0];
         var bidx = data[0].indexOf(" [");
        if (bidx > 0)
              v = data[0].substring(0, bidx);  //[] are disturbing mysql (E.g.; Air temperature [�C])
        var c = data[2];
        hIDs[idx] = await self.getParamID(mysqlCon, ghID, v, c, data);
    }
 });

【讨论】:

    猜你喜欢
    • 2019-12-18
    • 2017-08-12
    • 2016-07-21
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多