Passing callbacks The first thing we need to consider is how to pass the callback entry. In the most traditional XHR call, the callback function will be passed as the last parameter to the asynchronous function:
function asyncOperation(argument, callback)
When there are quite a few parameters, we can put the parameters into a JSON, so that the parameters are just like named parameters. Parameters can be selectively passed by parameter name. Parameters that are not passed are equivalent to using default values. This is a popular approach since Prototype:
function asyncOperation(argument, options)
However, both approaches have a disadvantage, that is, when changing a synchronous function to an asynchronous function (or a synchronous and asynchronous hybrid function), the function signature must be explicitly modified. Add one (or more) parameters at the end.
Since it is too common for us to introduce asynchronous functions at the bottom of the call stack, the cost of changing a lot of upper-level call function signatures is too high, so we still think of one that does not need to be modified. How to do function signature.
Here I refer to the .NET Framework's IAsyncResult design to concentrate all information about asynchronous operations into one object, thereby avoiding modifications to the function signature. Here, we assume that the calling prototype of an asynchronous function looks like this:
function asyncOperation(argument) {
operation = new Async.Operation();
setTimeout(function() { operation.yield("hello world"); }, 1000);
return operation;
}
In this code, we return an Operation object for passing callback functions in the future. At the same time, we simulated asynchronous return results through setTimeout, and the specific return method is the yield method.
Next, we also need to design a method to pass the callback function. Since we cannot overload the = operator like C#, we can only pass the callback function using a function:
var operation = asyncOperation(argument);
operation.addCallback(function(result) { alert(result); });
Do it in C# Such a design is unsafe because the asynchronous operation may complete before the callback is added. But it is safe to write like this in JavaScript, because JavaScript is single-threaded, and the synchronous addCallback of asyncOperation must be executed first, and the asynchronous yield in asyncOperation must be executed later.
Calling sequence
Someone may want to ask, if the user uses a synchronous method to call yield, does the execution sequence depend on the implementation of yield? That's right, but yeild is implemented once in the framework. We just need to make it asynchronous, so that even if it is called synchronously, the execution sequence will not be affected:
function psudoAsyncOperation(argument) {
operation = new Async.Operation();
operation .yield("hello world");
return operation;
}
var operation = asyncOperation(argument);
operation.addCallback(function(result) { alert(result); });
Even if the code is written like this, we can ensure that addCallback is executed before the actual logic of yield.
Post-event callback
Sometimes, users of the framework may actually write code that yields first and then addCallback. At this time, I think it is necessary to ensure that the callback function added in addCallback will be triggered immediately. Because the user adds this callback function, it means that he expects to notify this callback function when the asynchronous operation has a result, and this has nothing to do with whether the asynchronous operation is completed when the callback function is added. For this, we add another use case:
function psudoAsyncOperation(argument) {
operation = new Async.Operation();
operation.yield("hello world");
return operation;
}
var operation = asyncOperation(argument);
setTimeout(function() {
operation.addCallback(function(result) { alert(result); });
}, 1000);
Summary At this point, we have designed an asynchronous operation object named Async.Operation. How to implement the key yield method and addCallback method will be described in the next article. .