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