我正在尝试使用此功能从s3中的日志文件中获取一些总计数,然后将它们添加到总变量中以返回。但是我不能正确的回调。

我在foreach循环的末尾以及“
其他”结尾,但无论哪种情况,totalRowCount始终为零bcz语句立即开始执行。不确定我在做什么错,谢谢您的帮助。

function getRowCount2(token, params, callback){
  var totalRowCount = 0,
    TextDecoder = textEncoding.TextDecoder,
    i = 0;
  if(token) params.ContinuationToken = token;

  s3.listObjectsV2(params, function(err, data){

      i = data.Contents.length;
      data.Contents.forEach(function(file, index) {

          s3.getObject({Bucket: params.Bucket, Key: file.Key}, function(err, data) {

              zlib.gunzip(data.Body, function (err, result) {
                    var extractedData = JSON.parse(new TextDecoder("utf-8").decode(result));
                    totalRowCount = totalRowCount + parseInt(extractedData.rowcount, 10);

              });

              if ((index+1) == i){
                console.log('callback ' + totalRowCount);
                return callback('', totalRowCount);
              }
          });

       });

    if(data.IsTruncated)
      getRowCount2(data.NextContinuationToken, params, callback);
    else
      //return callback('', totalRowCount);
  });
}

getRowCount2('', params, function(error, data) {
     // check if equal
     if (mycount == data) { //success }
  });


我删除了日志记录和错误处理以帮助阅读。

最佳答案

您的问题是:


  如何在forEach循环结束时以及在我所有的异步函数完成对每个项目的工作之后一次调用回调函数?


回调的诀窍是不要混淆并在正确的地方做正确的事情。因为我们不在同步环境中,所以我们需要在包装器中添加一些额外的工作。

您的示例运行起来有点复杂。因此,我建立了一个可以重复使用的简化示例。它只计算几个文件的行数并在最后显示总和。

const fs = require("fs");
const files = ["a.txt","b.txt","c.txt","d.txt"];

function forEachOf (array, asynchFunction, callbackWhenFinished) {
    let nbCalls = 0;
    array.forEach(item => asynchFunction(item, () => {
        // Wrapper function responsible of calling callback function
        // only once asynchronous job is done on all items of array
        if (++nbCalls === array.length)
            callbackWhenFinished();
    }));
}

var nbLinesTotal = 0;

forEachOf(
    files,
    (name, callback) => {
        // Write your asynchronous function here
        fs.readFile(name, 'utf-8', (error, data) => {
            if (!error)
                nbLinesTotal += data.toString().split("\n").length;
            // Wrapper function is called here: it seamlessly decides if it's time to call the real callback
            callback();
        });
    },
    () => {
        // Write your callback function here.
        // It will be called only once
        console.log(nbLinesTotal);
    }
);




编辑:做一些研究,我发现有一个库可以完全执行我写的内容:async.js。值得您尝试一下:-)

关于node.js - Node.js foreach没有返回正确的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48429231/

10-13 04:22