簡體   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