繁体   English   中英

Console.log显示数组,但无法返回

[英]Console.log shows array but can't be returned

我刚开始使用诺言(我在节点中使用“ co”),所以我不完全确定此代码出了什么问题:

function* excelToJSON(excelFileNames) {
  var jsonData = [];

  for (let index = 0; index < excelFileNames.length; index++) {
    parseXlsx(excelFilesNames[index], function (err, data) {

      jsonData.push(data);
      console.log(jsonData); //***Shows data correctly
    });
  }

  console.log(jsonData); //***Empty array
  return yield jsonData;
}

它读取文件,将其转换,并且至少在循环中正确显示所有内容,但是一旦我们退出循环,数据似乎就会消失。 我也尝试过从循环中返回值之一,但这也不起作用。

编辑:parseXlsx来自此处的“ excel”模块: https : //github.com/trevordixon/excel.js ,老实说,我不确定是异步还是同步。 这似乎是它的代码,我知道'extractFiles'返回一个承诺,但是由于它随后经过'parseXlsx',所以我不确定之后会发生什么:

function parseXlsx(path, sheet, cb) {
  if (typeof cb === 'undefined') {
    cb = sheet;
    sheet = '1';
  }
  extractFiles(path, sheet).then(function(files) {
    cb(null, extractData(files));
  },
  function(err) {
    cb(err);
  });
};

EDIT2:我用来解决问题的方法是多个答案的结合,感谢大家。

 function* excelToJSON(excelFileNames) { return new Promise(function(resolve, reject) { var jsonData = []; if (excelFilesNames === null || excelFilesNames.length === 0) { reject(); } for (let index = 0; index < excelFilesNames.length; index++) { parseXlsx(excelFilesNames[index], function(err, data) { if (err) { throw err; } jsonData.push(data); if (jsonData.length === excelFilesNames.length) { resolve(jsonData); } }); } }); } 

只使用一个计数器,何时返回,请尝试类似的操作。

function* excelToJSON(excelFileNames) {
var jsonData = [];
var count=0;
  for (let index = 0; index < excelFileNames.length; index++) {
    parseXlsx(excelFilesNames[index], function (err, data) {

      jsonData.push(data);
      console.log(jsonData); //***Shows data correctly
          if(count==excelFileNames.length){
                console.log(jsonData); 
                return yield jsonData;
           }
        count++
    });
  }
}

原因:

parseXlsx是一个异步调用,因此您不会立即获取数据。


怎么修:

在回调中做事。

function* excelToJSON(excelFileNames, callback) {
  var jsonData = [];

  for (let index = 0; index < excelFileNames.length; index++) {
    parseXlsx(excelFilesNames[index], function (err, data) {

      jsonData.push(data);
      console.log(jsonData); //***Shows data correctly

      callback(jsonData);    // do what you want with the jsonData here.
    });
  }

  // console.log(jsonData); //***Empty array
  // return yield jsonData;
}

因此,这里发生的是您的代码仅通过for块运行,调用了parseXlsx几次,但从未真正等待它完成。

因此,这就是为什么先出现空数组日志,然后是带有“正确数据”的日志的原因。 查找javascript事件循环,以更好地了解异步函数的工作方式。

本质上,您需要的是在完成时解决的承诺,或者获得完成后将调用的回调函数。

jsonData.push(data);完成时,您会知道 只要您的excelFileNames数组被调用过多次。

例如:

function excelToJSON(excelFileNames) {
  var deferred = Promise.defer();
  var jsonData = [];

  for (let index = 0; index < excelFileNames.length; index++) {
    parseXlsx(excelFilesNames[index], function (err, data) {

      jsonData.push(data);
      console.log(jsonData); //***Shows data correctly
      if (jsonData.length === excelFileNames.length) {
        deferred.resolve(jsonData);
      }
    });
  }

  return deferred.promise;
}

// And use it as a promise:

var exelToJsonPromise = excelToJSON(["apples.xlsx", "pears.xlsx]);

exelToJsonPromise.then(function(jsonData){ 
  console.log(jsonData); // Now this will have everything in it.
});

Node.js是一个异步框架。 您遇到的情况是parseXlsx外部的console.log(jsonData)在内部的console.log(jsonData)之前被调用。 您可以尝试像这样的异步瀑布方法。

var pushData = function (err, data) {
    jsonData.push(data);
    console.log(jsonData);
};

function* excelToJSON(excelFileNames) {
    var jsonData = [];
    async.waterfall([
        function(){
            for (let index = 0; index < excelFileNames.length; index++) {
                parseXlsx(excelFilesNames[index], pushData);
            }
        }
    ], function() {
           console.log(jsonData);
           return yield jsonData;
    });
}

您可以在此处了解更多信息。

PS。 在循环内部定义函数也不是一个好习惯。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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