防止回调被调用两次

时间:2015-02-21 17:00:24

标签: node.js

我有以下代码,但由于它是异步行为(我想),回调被调用两次。我正在使用node-unzip解压缩我从互联网上下载的文件。

function DownloadAndExtract(file, callback) {
    log.debug("Starting download of "+file);
    fse.ensureDirSync(tempPath);
    var extractor = unzip.Extract({path: tempPath});
    extractor.on("close", function() {
        log.debug("Done downloading "+file);
        return callback(null, file);
    });
    extractor.on("error", function (err) {
        log.error("Extracting download "+file+": "+JSON.stringify(err, null, "\t"));
        return callback(err, null); // THIS IS LINE 274
    });

    var url = "";
    if(file == "WONEN") {
        url = "https://example.com/file1.zip";
    }else if(file == "BOG") {
        url = "https://example.com/file2.zip";
    }

    if(url != "") {
        request
            .get(url)
            .on("error", function (err) {
                return callback(err, null);
            })
            .pipe(extractor);
    }else{
        return callback(new Error("Invalid file indicator: '"+file+"'"), null);
    }
}

我希望返回实际上退出所有正在运行的异步函数,但这显然是无稽之谈。现在,我不断得到的错误如下:

/home/nodeusr/huizenier.nl/node_modules/async/lib/async.js:30
        if (called) throw new Error("Callback was already called.");
                          ^
Error: Callback was already called.
    at /home/nodeusr/huizenier.nl/node_modules/async/lib/async.js:30:31
    at /home/nodeusr/huizenier.nl/node_modules/async/lib/async.js:251:21
    at /home/nodeusr/huizenier.nl/node_modules/async/lib/async.js:575:34
    at Extract.<anonymous> (/home/nodeusr/huizenier.nl/realworks.js:274:10)
    at Extract.emit (events.js:129:20)
    at Parse.<anonymous> (/home/nodeusr/huizenier.nl/node_modules/unzip/lib/extract.js:24:10)
    at Parse.emit (events.js:107:17)
    at /home/nodeusr/huizenier.nl/node_modules/unzip/lib/parse.js:60:12
    at processImmediate [as _immediateCallback] (timers.js:358:17)

log.error()来电的输出如下: 21-02-2015 03:00:05 - [ERROR] Extracting download WONEN: {}所以我很困惑。没有真正的错误,那么为什么会发出事件?

如何阻止回调在此处被调用两次?联系包的创建者或创建一个解决方案?

代码调用DownloadAndExtract

async.parallel([
    function (callback) {
        DownloadAndExtract("WONEN", callback);
    },
    function (callback) {
        DownloadAndExtract("BOG", callback);
    }
],
function (err, done) {
    if(err) return log.error("Update entries: "+JSON.stringify(err, null, "\t"));
    // Do different logic if no error
});

修改

我的一个尝试是在函数中声明var callbackAlreadyCalled = false,并且在我调用回调的任何给定点,我做

if(!callbackAlreadyCalled) {
    callbackAlreadyCalled = true;
    return callback(callback params);
}

这是一个好方法还是我能以更好的方式处理它?<​​/ p>

编辑2

已经发现空错误是由使用JSON.stringify()时错误无法正常引起的,但问题不会改变。

1 个答案:

答案 0 :(得分:0)

看起来你有瀑布错误调用。 当你调用请求时,它调用提取器然后如果有错误它调用提取器的on_error然后调用请求的on_error。

尝试统一错误的回报或仅调用一次。进行测试,删除其中一个“on('error'”验证。