Console.log显示数组但不能返回

时间:2017-04-11 08:36:05

标签: javascript node.js co

我很擅长使用p​​romises(我在节点中使用' 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来自&#39; excel&#39;模块在这里:https://github.com/trevordixon/excel.js 说实话,我不完全确定它是异步还是同步。这似乎是它的代码,我知道&#39; extractFiles&#39;返回一个承诺但是因为它然后通过了parseXlsx&#39;我不确定之后会发生什么:

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: 我曾经解决过的问题是多个答案的组合,感谢大家。

&#13;
&#13;
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);
        }
      });
    }
  });
}
&#13;
&#13;
&#13;

4 个答案:

答案 0 :(得分:3)

只使用计数器&amp;什么时候回来,尝试这样的事情。

If (userlist.count > 0) Then
    If (Filter()) Then
        users = From u In userlist Order By (If(u.name ) username,1,0) 
                descending u.name ascending 
    Else
        users = From u In userlist
                Select u.name Distinct Order By u.name Ascending
    End If
Else
    users = New List(Of String)
End If

答案 1 :(得分:2)

<强>原因:

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;
}

答案 2 :(得分:1)

所以这里发生的事情是你的代码只运行了阻塞,几次调用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.
});

答案 3 :(得分:1)

Node.js是一个异步框架。在你的情况下发生的事情是parseXlsx之外的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;
    });
}

您可以详细了解docker secrets

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