我的印象是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完成,即使它们可以并行运行也没有问题。

有什么优雅的方法可以解决这个问题吗?

谢谢,
一月

最佳答案

鉴于此,如果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.');
});

09-17 21:18