可停止的异步任务序列

时间:2018-04-16 01:23:45

标签: javascript asynchronous

实现可停止的异步任务列表的最佳方法是什么? 任务数量不固定。

我找到了一种方法,但我想知道是否有更好的方法来实现这样的事情。此外代码看起来相当脏,这让我觉得这可能不是那样的。 主要问题是:

  • 检测请求结束的时间。
  • 能够执行一系列异步函数,无论剩下的任务如何,都可以在一个点退出进程。

对于问题(2),我发现了一种不错的方法,即使用async.waterfall。将值发送到回调的error参数会导致所有进程停止 现在是肮脏的部分,为(1)。为了实现这一点,每个任务都必须监听对象中的值更改(让我们停留,序列的状态),以便检测何时需要退出进程。

因此,实现的原型看起来像这样:

let sequenceState = new Proxy(
    {
        stopped: false,
        onStop: () => { }
    },
    {
        set: function (target, prop, value) {
            if (prop === "stopped") {
                target.stopped = value;
                if (value)
                    target.onStop();
            } else {
                target[prop] = value;
            }
        }
    }
);

function stop() {
    sequenceState.stopped = true;
}

function task1(callback) {
    console.log("Task 1...");
    let to = setTimeout(() => {
        console.log("Done after 2000 ms");
        callback();
    }, 2000);

    sequenceState.onStop = () => {
        clearTimeout(to);
        callback(true);
    };
}

function task2(callback) {
    console.log("Task 2...");
    let to = setTimeout(() => {
        console.log("Done after 3000 ms");
        callback();
    }, 3000);

    sequenceState.onStop = () => {
        clearTimeout(to);
        callback(true);
    };
}

async.waterfall(
    [
        task1,
        task2
    ],
    function (err, results) {
        console.log("End of tasks");
    });

setTimeout(() => {
    console.log("Stopped after 2500 ms !");
    stop();
}, 2500);
<script src="https://cdn.jsdelivr.net/npm/async@2.6.0/dist/async.min.js"></script>

有没有人有更好的方法来实现这个?

0 个答案:

没有答案