【问题标题】:Callback was already called回调已被调用
【发布时间】:2017-03-22 22:02:39
【问题描述】:

当我尝试在 node.js 的 async.waterfall 中使用 list.forEach 方法时,我收到了错误消息: if (fn === null) throw new Error("Callback is already called.");

错误:回调已被调用。

我想要的是对目录中的每个文件进行一些更改。

/**
 * Created by slow_time on 2017/3/22.
 */
var fs = require('fs');
var async = require('async');
var _dir = './data/';
//writeStream is used to log something
var writeStream = fs.createWriteStream('log.txt',
    {
        'flags': 'a',
        'encoding': 'utf8',
        'mode': 0666
    });

try {
    //use the method waterfall
    async.waterfall([
        //read the directory
        function (callback) {
            fs.readdir(_dir, function (err, files) {
                callback(err, files);
            });
        },
        function (files, callback) {
            //Here is what I guess, something wrong with it
            files.forEach(function (name) {
                callback(null, name);
            });
        },
        //The code below is right, I think.
        function (file, callback) {
            fs.stat(_dir + file, function (err, stats) {
                if(stats.isFile())
                    callback(err, stats, file);
            });
        },
        //judge whether it is a file or a directory
        function (stats, file, callback) {
            fs.readFile(_dir + file, 'utf8', function (err, data) {
                callback(err, file, data);
            });
        },
        // do some changes to the file content
        function (file, data, callback) {
            var adjData = data.replace(/somecompany\.com/g, 'burningbird.net');
            fs.writeFile(_dir + file, adjData, function (err) {
                callback(err, file);
            });
        },
        //write the changes back to the file
        function (file, callback) {
            writeStream.write('changed ' + file + '\n', 'utf8', function (err) {
                callback(err, file);
            });
        }
    ], function (err, result) {
        if(err) throw err;
        console.log('modified ' + result);
    });
} catch(err) {
    console.log(err);
}

【问题讨论】:

  • 您在哪一行出现错误?
  • 您不能使用async.waterfall 为这样的列表中的每个元素运行代码。您需要使用async.map
  • 谢谢,首先。你的意思是我永远不能在 async.waterfall 中使用 forEach 方法?但它是书中的演示。以及如何在我的情况下使用 async.map?

标签: javascript node.js asynchronous


【解决方案1】:

当您在 foreach 中调用回调时,它会给出错误。 你的代码 -

files.forEach(function (name) {
   callback(null, name);
});

回调应该在您完成操作后只调用一次。 所以做这个改变:

files.forEach(function (name) {

});
callback(null, name);

【讨论】:

  • 如果我按照您的建议更改我的,我将无法浏览列表中的所有文件
  • 那么你可以使用promise来接受这个。比如 foreach().then(callback)
  • 或者你可以使用这个异步方法:- async.each(items, // 第二个参数是每个项目传递给 function(item, callback){ // 调用一个异步函数,通常是一个 save() 到 DB callback(); }, // 第三个参数是当一切都完成时调用的函数 function(err){ // 现在所有任务都完成了 console.log("done") } );跨度>
猜你喜欢
  • 2017-10-13
  • 2016-01-26
  • 2018-09-14
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
  • 2016-11-22
  • 2017-03-02
相关资源
最近更新 更多