async.auto:第一次出错后停止整个链

时间:2016-02-08 16:29:12

标签: javascript node.js async.js

我的印象是async.auto的行为是,如果其中一个任务返回err,则会调用全局回调并显示此错误并全部后续任务不会执行。毕竟,他们为什么会这样?已调用全局回调,因此已报告错误。

事实证明,只有依赖于错误任务的任务才会运行,其余的将会运行。

'use strict';

var async = require('async');

async.auto({
    downloadAudio: function (callback) {
        console.log("downloading audio...");
        setTimeout(function () {
            console.log("downloaded audio.");
            callback();
        }, 10000);
    },
    downloadScript: function (callback) {
        console.log("downloading script...");
        setTimeout(function () {
            return callback(new Error("ERROR downloading script!"));
        }, 1000);
    },
    preprocessAudio: ['downloadAudio', function (callback) {
        console.log("preprocessing audio...");
        setTimeout(function () {
            console.log("done preprocessing audio.");
            callback();
        }, 5000);
    }]
}, function (err) {
    if (err) {
        return console.error(err.message);
    }

    console.log('done.');
});

在此代码段中,downloadAudiodownloadScript将立即并行运行,preprocessAudio取决于downloadAudio。问题是当downloadScript返回err时,preprocessAudio仍然会运行,即使没有任何意义,因为事情已经整体失败了:

downloading audio...
downloading script...
ERROR downloading script!
downloaded audio.
preprocessing audio...
done preprocessing audio.

我知道,我可以preprocessAudio依赖downloadScript,但这意味着preprocessAudio会等待downloadScript完成,即使它们可以并行运行一个问题。

有没有优雅的方法来解决这个问题?

谢谢, 扬

1 个答案:

答案 0 :(得分:0)

如果downloadScript失败了,那么你不希望preprocessaudio运行,preprocessaudio确实“依赖”其他两个函数。

只需添加依赖项,所有这些都应该正常工作。

'use strict';

var async = require('async');

async.auto({
    downloadAudio: function (callback) {
        console.log("downloading audio...");
        setTimeout(function () {
            console.log("downloaded audio.");
            callback();
        }, 10000);
    },
    downloadScript: function (callback) {
        console.log("downloading script...");
        setTimeout(function () {
            return callback(new Error("ERROR downloading script!"));
        }, 1000);
    },
    preprocessAudio: ['downloadAudio', 'downloadScript', function (callback) {
        console.log("preprocessing audio...");
        setTimeout(function () {
            console.log("done preprocessing audio.");
            callback();
        }, 5000);
    }]
}, function (err) {
    if (err) {
        return console.error(err.message);
    }

    console.log('done.');
});