[英]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.