Home Stoppable sequence of async tasks
Reply: 0

Stoppable sequence of async tasks

user2725
1#
user2725 Published in April 22, 2018, 10:07 pm

What would be the best way to implement a stoppable list of asynchronous tasks ? The number of tasks aren't fixed.

I've found a way but I'm wondering if there is a better way to implement such thing. Also the code looks rather dirty, which makes me think that that's probably not the way to go. The main issues are:

  • Detect when the end of tasks is requested.
  • Be able to execute a chain of asynchronous functions, with the possibility of quitting the process at one point, regardless of the remaining tasks.

For issue (2), I found a decent way, which is by using async.waterfall. Sending a value to the error parameter of the callback causes all the processes to stop.
Now comes the dirty part, for (1). To achieve this, each task has to listen for a value change in a object (let's stay, the state of the sequence) in order to detect when quitting the process is required.

So, a prototype of the implementation looks like that:

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>

Does anyone have a better way of implementing this ?

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.310387 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO