Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active November 5, 2017 17:51
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbostock/7606141 to your computer and use it in GitHub Desktop.
Save mbostock/7606141 to your computer and use it in GitHub Desktop.
Infinite Queue

A little demo of an infinitely long-living queue with 6 parallel slots for tasks. The sentinel task that never invokes the callback prevents the queue from ending, even if there are not any currently-active tasks.

There is a downside to this approach, however, which is that the queue’s internal task results array increases in length by one with each task, even though in this case the queue’s results are never triggered. Thus, be careful using this pattern if you really expect the queue to live indefinitely. Alternatively, it might be worth extending Queue’s minimal API to allow tasks to be processed without tracking their return value.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
padding: 40px;
}
div {
background: steelblue;
font-family: sans-serif;
color: white;
padding: 4px;
margin-bottom: 2px;
text-shadow: 0 1px 0 #000;
overflow: hidden;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/queue.v1.min.js"></script>
<script>
var count = 0,
duration = d3.random.normal(5000, 500),
parallelism = 6;
var q = queue(parallelism + 1);
q.defer(function sentinel() {}); // run forever
d3.range(10).forEach(repeat); // a few initial tasks
function repeat() {
q.defer(function(callback) {
d3.select("body").append("div")
.style("width", "0px")
.text(++count)
.transition()
.duration(duration())
.style("width", "480px")
.transition()
.duration(250)
.style("margin-top", function() { return -this.clientHeight + "px"; })
.style("opacity", 0)
.each("end", function() { callback(null); })
.remove();
setTimeout(repeat, duration());
});
}
</script>
@culli
Copy link

culli commented Nov 5, 2017

For D3 v4:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
    body {
        padding: 40px;
    }

    div {
        background: steelblue;
        font-family: sans-serif;
        color: white;
        padding: 4px;
        margin-bottom: 2px;
        text-shadow: 0 1px 0 #000;
        overflow: hidden;
    }
</style>

<body>

    <!-- all of d3 -->
    <!-- <script src="//d3js.org/d3.v4.min.js"></script> -->

    <!-- or use standalone modules, order matters for the following dependencies! -->
    <script src="https://d3js.org/d3-color.v1.min.js"></script>
    <script src="https://d3js.org/d3-dispatch.v1.min.js"></script>
    <script src="https://d3js.org/d3-ease.v1.min.js"></script>
    <script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
    <script src="https://d3js.org/d3-selection.v1.min.js"></script>
    <script src="https://d3js.org/d3-timer.v1.min.js"></script>
    <script src="https://d3js.org/d3-transition.v1.min.js"></script>
    <script src="https://d3js.org/d3-random.v1.min.js"></script>
    <script src="https://d3js.org/d3-queue.v3.min.js"></script>
    <script src="https://d3js.org/d3-array.v1.min.js"></script>
    <script>
        var count = 0,
            duration = d3.randomNormal(5000, 500),
            parallelism = 6;

        var q = d3.queue(parallelism + 1);

        q.defer(function sentinel() { }); // run forever

        d3.range(10).forEach(repeat); // a few initial tasks

        function repeat() {
            console.log('repeat')
            q.defer(function (callback) {
                d3.select("body").append("div")
                    .style("width", "0px")
                    .text(++count)
                    .transition()
                    .duration(duration())
                    .style("width", "480px")
                    .transition()
                    .duration(250)
                    .style("margin-top", function () { return -this.clientHeight + "px"; })
                    .style("opacity", 0)
                    .on("end", callback)
                    .remove();

                setTimeout(repeat, duration());
            });
        }

    </script>
</body>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment