JavaScript multithreaded asynchronous queues

Source: Internet
Author: User
Tags object log return thread


First, you need to know the general usage of jquery.deferred, and then let's get to the point:



Library code:


/ *!
 * Multi-threaded asynchronous queue
 * Depends on jQuery 1.8+ (If you are using 1.6 or 1.7, just replace the then method in the source code with the pipe method)
 * /

/ **
 * @n {Number} positive integer, number of threads
 * /
function Queue (n) {
    n = parseInt (n 1, 10);
    return new Queue.prototype.init ((n && n> 0)? n: 1)
}

Queue.prototype = {
    init: function (n) {
        this.threads = [];
        this.taskList = [];

        while (n--) {
            this.threads.push (new this.Thread)
        }
    },

    / **
     * @callback {Fucntion} callback function when promise object done, its return value must be a promise object
     * /
    push: function (callback) {
        if (typeof callback! == 'function') return;

        var index = this.indexOfIdle ();

        if (index! = -1) {
            this.threads [index] .idle (callback)
            try {console.log ('Thread-' + (index + 1) + 'accept the task!')} catch (e) {}
        }
        else {
            this.taskList.push (callback);

            for (var i = 0, l = this.threads.length; i <l; i ++) {

                (function (thread, self, id) {
                    thread.idle (function () {
                        if (self.taskList.length> 0) {
                            try {console.log ('Thread-' + (id + 1) + 'accept the task!')} catch (e) {}

                            var promise = self.taskList.pop () (); // The correct return value should be a promise object
                            return promise.promise? promise: $ .Deferred (). resolve (). promise ();
                        } else {
                            return $ .Deferred (). resolve (). promise ();
                        }
                    })
                }) (this.threads [i], this, i);

            }
        }
    },
    indexOfIdle: function () {
        var threads = this.threads,
            thread = null,
            index = -1;

        for (var i = 0, l = threads.length; i <l; i ++) {
            thread = threads [i];

            if (thread.promise.state () === 'resolved') {
                index = i;
                break;
            }
        }

        return index;
    },
    Thread: function () {
        this.promise = $ .Deferred (). resolve (). promise ();

        this.idle = function (callback) {
            this.promise = this.promise.then (callback)
        }
    }
};

Queue.prototype.init.prototype = Queue.prototype;


Using the example:


var queue = new Queue (3); // create a queue with 3 threads

// task-1
    queue.push (function () {
        var defer = $ .Deferred ();

        setTimeout (function () {
            defer.resolve ()
        }, 8000);

        return defer.promise ()
    })

// task-2
    queue.push (function () {
        var defer = $ .Deferred ();

        setTimeout (function () {
            defer.resolve ()
        }, 2000);

        return defer.promise ()
    })

// task-3
    queue.push (function () {
        var defer = $ .Deferred ();

        setTimeout (function () {
            defer.resolve ()
        }, 6000);

        return defer.promise ()
    })

// task-4
    queue.push (function () {
        var defer = $ .Deferred ();

        setTimeout (function () {
            defer.resolve ()
        }, 3000);

        return defer.promise ()
    })

// task-5
    queue.push (function () {
        var defer = $ .Deferred ();

        setTimeout (function () {
            defer.resolve ()
        }, 2000);

        return defer.promise ()
    })

// task-6
    queue.push (function () {
        var defer = $ .Deferred ();

        setTimeout (function () {
            defer.resolve ()
        }, 2000);

        return defer.promise ()
    }) 


The console has a function that shows Queue.push (call it a task) and which process is ultimately processed



Once instantiated, the 3 threads in the queue are in an idle state
assigning task-1 to Thread 1, this task takes 8s
assigning task-2 to Thread 2, this task takes 2s
assigning task-3 to Thread 3, this task takes 6s

Because there are currently no idle processes, task-4, task-5, task-6 are added to the waiting area within the queue

Because task-2 takes 2s, process 2 is first liberated, then TASK-4 is assigned to process 2, and so on, the final console shows the process usage: 1, 2, 3, 2, 2, 3



The usage scenario for this library is this
1, as I recently did the project:
The host is doing live, many viewers will give the host gifts, these gifts are JS animation effects, the page can display up to three gift effects

2. Asynchronous requests that depend on each other
A request relies on B request, B request relies on C request, C request relies on ...
This requirement allows us to use this library to implement this:


var queue = new Queue (1);

Request C
Queue.push (function () {return
$.ajax (); JQ Ajax returns exactly the Promise Object
})

//Request B
queue.push (function () {return
$.ajax ();
})

Request a
Queue.push (function () {return
$.ajax ();
})


Queue.push (callback) callback must return a Promise object




Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.