In the previous article, we talked about implementing a Cat.Async.Operation class, passing the callback function through the Addcallback method, and returning the callback result through the yield method. Now we're going to implement this class.
Class structure
First, let's build a shelf and list all the variables that need to be used. We need an array to hold the list of callback functions, a flag bit to indicate whether the asynchronous operation is complete, or to learn IAsyncResult, plus a state that allows the performer of the asynchronous operation to expose the custom execution status externally, and a variable to save the asynchronous operation result.
var Cat = {};
Cat.Async = {
Operation: {
var callbackQueue = [];
this.result = undefined;
this.state = "waiting";
this.completed = false;
}
}
Addcallback method
Next, we want to implement the Addcallback method, its job is very simple, is to put the callback function in the Callbackqueue. Also, if the completed is true at this time, the asynchronous operation has been yield, this callback is called immediately.
this.yield = function(callback) {
callbackQueue.push(callback);
if (this.completed) {
this.yield(this.result);
}
return this;
}
Let's assume that the yield method pulls the callback function in the Callbackqueue one at a time and then calls it, so if compeleted is true, then the yield is OK with the existing result again, This yield naturally invokes the callback function that was added to the callbackqueue.
As for the final return of this; In order to facilitate the jquery style of chain writing, you can add multiple callback functions consecutively through a dot-number separation:
asyncOperation(argument)
.addCallback(firstCallback)
.addCallback(secondCallback);
Yield method
Finally, we will implement the yield method. It needs to remove the callback function in the Callbackqueue, and then call it all over again, and make sure the operation is asynchronous.
this.yield = function(result) {
var self = this;
setTimeout(function() {
self.result = result;
self.state = "completed";
self.completed = true;
while (callbackQueue.length > 0) {
var callback = callbackQueue.shift();
callback(self.result);
}
}, 1);
return this;
}
By using settimeout, we ensure that the actual operation of the yield is done asynchronously. We then update the results of the user's incoming yield and the related state to the object properties, and then traverse Callbackqueue to invoke all the callback functions.