In the last issue, we discussed the design of the queue management component and gave it a loud and unique name: Smart Queue. This time, we are going to put the previous design results into practice and implement it with code.
First, we need to consider its source file layout, that is, decide how to split the code into independent files. Why do this? Remember at the end of last issue I mentioned that this component will use "external code"? In order to distinguish the purpose of the code, it was decided to divide the code into at least two parts: the external code file and the Smart Queue file.
Differentiating purposes is only one, and second, dispersing them into independent files is beneficial to code maintenance. Imagine that one day in the future you decide to add some new extended functions to the existing basic functions of queue management, or package it into a component that implements a specific task, but you want to maintain the existing functions (internal Implementation) and calling method (external interface) remain unchanged, then writing the new code into a separate file is the best choice.
Well, next time we will focus on the topic of file layout, now let’s get to the point. The first step, of course, is to create its own namespace for the component. All the code of the component will be restricted to this top-level namespace:
var SmartQueue = window.SmartQueue || {};
SmartQueue.version = '0.1';
During initialization, if you encounter a namespace conflict, pull it over and use it. Usually this conflict is caused by repeated reference to component code, so "pull over" will rewrite the object with the same implementation; in the worst case, if there happens to be another object on the page also called SmartQueue, that's embarrassing , I would override your implementation - if there are no further naming conflicts, basically the two components can run without incident. Also give it a version number.
Next, create three queues for SmartQueue according to three priorities:
var Q = SmartQueue.Queue = [[], [], []];
Each is an empty array because no tasks have been added yet. And by the way, create a "shortcut" for it. If you want to access the array later, just write Q[n].
Next, our protagonist Task makes a grand appearance - how to create a new Task is defined here:
I won’t go into the specific details inside. With necessary comments, generally our code can be self-describing, and the same is true for subsequent codes. Here we tell the customer (user): If you want to create a new SmartQueue.Task instance, you must pass at least one parameter to this constructor (the last three can be omitted for default processing), otherwise an exception will be thrown.
But this is not enough. Sometimes, customers want to clone a new instance from an existing Task, or repair a "healthy body" (a real Task object instance) from a "disabled body" (an object with some Task attributes), by The above construction method is a bit uncomfortable - the customer has to write like this:
var task1 = new SmartQueue.Task(obj.fn, 1, '', obj.dependencies);
Source: Alipay UED
var T = SmartQueue.Task = function(fn, level, name, dependencies) {
if(typeof fn !== FUNCTION) {
throw new Error('Invalid argument type: fn.');
}
this.fn = fn;
this.level = _validateLevel(level) ? level : LEVEL_NORMAL;
// detect type of name
this.name = typeof name === STRING && name ? name : 't' + _id++;
// dependencies could be retrieved as an 'Object', so use instanceof instead.
this.dependencies = dependencies instanceof Array ? dependencies : [];
};