【问题标题】:Node.js async.each - "callback was already called"Node.js async.each - “回调已被调用”
【发布时间】:2016-01-26 00:24:50
【问题描述】:

我是一个 node.js 菜鸟,正在尝试进行一些文件处理。我正在使用 async 来处理一组文件,但从未调用过回调函数。我相信这是由于两次调用 next() 函数,但我看不到我在哪里做这个。如果我注释掉最后一个“return next()”,我完成时没有错误,但最终的回调不会执行。如果我取消注释掉这一行,我会收到错误消息“回调已被调用”。任何帮助将不胜感激。代码如下:

/*jslint node: true */
"use strict";

var fs = require('fs'),
    dive = require('dive'),
    subdirs = require('subdirs'),
    async = require('async'),
    currentYear = new Date().getFullYear(),
    cpFile = __dirname + "/" + "header.txt",
    noCopy = __dirname + "/" + "noCopyright.txt",
    currentHeads = __dirname + "/" + "currentHeaders.txt",
    reYear = /\s(\d{4})[-\s]/i, // matches first 4 digit year
    reComment = /(\/\*(?:(?!\*\/).|[\n\r])*\*\/)/, // matches first multi-line comment
    allHeaders = {},
    stringObj,
    year,
    top;

function needsHeader (file) {
    if ((file.match(/.*\.js$/) || file.match(/.*\.less$/) || file.match(/.*\.groovy$/) || file.match(/.*\.java$/) || file.match(/.*\.template$/) || file.match(/.*\.html$/))) {
        fs.appendFile(noCopy, file + "\n", function (err) {
            if (err) {
                return console.log(err);
            }
        });
    }
}

fs.readFile(cpFile, 'utf8', function (err, copyRight) {
    if (err) {
        return console.log(err);
    }
    subdirs(__dirname, 4, function (err, dirs) {
        if (err) {
            return console.log(err);
        }
        async.each(dirs, function (dir, next) {
            if (! dir.match(/.*\/src$/)) {
                return next();
            } else {
                dive(dir, {all: false}, function (err, file) {
                    if (err) {
                        return next(err);
                    } else {
                        fs.readFile(file, 'utf8', function (err, data) {
                            if (err) {
                                return next(err);
                            } else {
                                if (data.match(reComment) && (file.match(/.*\.js$/) || file.match(/.*\.less$/) || file.match(/.*\.groovy$/) || file.match(/.*\.java$/) || file.match(/.*\.template$/))) {
                                    top = data.match(reComment)[0];
                                    if (top.match(reYear)) {
                                        year = top.match(reYear)[1];
                                        if (allHeaders[year]) {
                                            allHeaders[year].push(file);
                                        } else {
                                            allHeaders[year] = [file];
                                        }
                                    } else {
                                        needsHeader(file);
                                    }
                                } else {
                                    needsHeader(file);
                                }
                                return next();
                            }
                        });
                    }
                });
            }
        }, function (err) {
            if (err) {
                console.log(err);
            }
            stringObj = JSON.stringify(allHeaders, null, 4);
            fs.writeFile(currentHeads, stringObj, function (err) {
                if (err) {
                    return console.log(err);
                }
            });

        });
    });
});

【问题讨论】:

  • dive 是否多次调用您的回调?

标签: javascript node.js asynchronous


【解决方案1】:

它希望您为每个目录调用next(),并且您正在为目录中找到的每个文件调用它。因此,一旦某个目录包含 2 个或更多文件,就会出现错误。

要解决此问题,请尝试在潜水完成时致电 next()。见dive documentation

complete [可选] 可以定义第二个回调,即调用, 处理完所有文件后。它不需要任何参数。

dive(dir, {all: false}, function (err, file) {
  if (err) {
    return next(err);
  } else {
      // your file handling code here
  }
}, function complete() {
  next();
});

【讨论】:

  • 要建立在@ataman 的出色答案的基础上,您可以将function complete() { next(); } 替换为next
猜你喜欢
  • 2016-11-22
  • 2017-06-23
  • 2016-08-19
  • 1970-01-01
  • 1970-01-01
  • 2017-10-13
  • 2018-09-14
  • 2023-03-21
  • 1970-01-01
相关资源
最近更新 更多