Home  >  Article  >  Web Front-end  >  JavaScript Asynchronous Calling Framework (Part 6 - Examples & Patterns)_javascript skills

JavaScript Asynchronous Calling Framework (Part 6 - Examples & Patterns)_javascript skills

WBOY
WBOYOriginal
2016-05-16 18:48:391090browse
Encapsulating Ajax
The original purpose of designing Async.Operation is to solve the problem that Ajax calls need to pass callback parameters. For this reason, we first encapsulate the Ajax request into Async.Operation. I'm using jQuery here. Of course, no matter what basic library you use, you can do this simple encapsulation when using Async.Operation.
Copy code The code is as follows:

var Ajax = {};

Ajax.get = function(url, data) {
var operation = new Async.Operation();
$.get(url, data, function(result) { operation.yield(result); }, " json");
return operation;
};

Ajax.post = function(url, data) {
var operation = new Async.Operation();
$. post(url, data, function(result) { operation.yield(result); }, "json");
return operation;
};

in what I am calling In the server-side API, only GET and POST are required, and the data is all JSON, so I directly blocked other Ajax options provided by jQuery and set the data type to JSON. In your project, you can also use a similar method to encapsulate Ajax into several methods that only return Async.Operation, and encapsulate all the options provided by jQuery in the Ajax layer, and no longer expose these options to the upper layer.

Calling Ajax
After encapsulating Ajax, we can start to concentrate on writing business logic.

Suppose we have a Friend object, its get method is used to return a single friend object, and the getAll method is used to return all friend objects. Corresponding to this are two server-side APIs. The friend interface will return a single friend JSON, and the friendlist interface will return a JSON consisting of all friend names.

First let’s look at how to write the more basic get method:
Copy the code The code is as follows:

function get(name) {
return Ajax.get("/friend", "name=" encodeURIComponent(name));
}

That’s it Simple? Yes, if the JSON structure returned by the server-side API is exactly the friend object structure you want. If the JSON structure and the friend object structure are heterogeneous, you may need to add some code to map JSON to objects:
Copy code The code is as follows:

function get(name) {
var operation = new Async.Operation()
Ajax.get("/friend", "name=" encodeURIComponent(name ))
.addCallback(function(json) {
operation.yield(createFriendFromJson(json));
});
return operation;
}

Ajax Queue
The next thing we have to write is the getAll method. Because the friendlist interface only returns a list of friend names, after obtaining this list, we have to call the get method one by one to obtain specific friend objects. Considering that calling multiple friend interfaces at the same time may trigger the server's anti-attack strategy and result in being locked up in a dark room for a period of time, calls to the friend interface must be queued.
Copy code The code is as follows:

function getAll(){
var operation = new Async.Operation();
var friends = [];
var chain = Async.chain();
Ajax.get("/friendlist", "")
.addCallback(function( json) {
for (var i = 0; i < json.length; i ) {
chain.next(function() {
return get(json.shift())
. addCallback(function(friend) { friends.push(friend); });
});
}
chain
.next(function() { operation.yield(friends); })
.go();
})
return operation;
}

Here, we assume that the JSON returned by the friendlist interface is an Array. After obtaining this Array, we construct an asynchronous call queue of equal length. The logic of each call is the same - take out the first friend in the Array. name, use the get method to obtain the corresponding friend object, and then put the friend object into another Array. At the end of the call queue, we append another call to return the Array that holds the friend object.

In this example, we did not use the feature of the call queue to pass the result of the previous function to the next function, but it is enough to demonstrate the use of the call queue - allowing multiple bottom layers to perform Ajax requests Asynchronous operations are executed blockingly in a fixed order.

Since the underlying asynchronous function returns Async.Operation, you can pass it directly to the next method, or you can wrap it with an anonymous function and pass it to the next method, and only one return is needed inside the anonymous function.

Delay function
In the above example, the queue is used to avoid triggering the server's anti-attack strategy, but sometimes this is not enough. For example, the server requires at least 500 milliseconds between two requests, otherwise it will be considered an attack, then we will insert this interval into the queue.

Manually adding setTimeout to the anonymous function originally called by the next method is one way, but why don’t we write an auxiliary function to solve this kind of problem? Let's write a helper method and integrate it seamlessly with Async.Operation.
Copy code The code is as follows:

Async.wait = function(delay, context) {
var operation = new Async.Operation();
setTimeout(function() { operation.yield(context); }, delay);
return operation;
};

Async.Operation.prototype.wait = function(delay, context) {
this.next(function(context) { return Async.wait(delay, context); });
}

With this helper method, we can easily implement an interval of 500 milliseconds between each Ajax request in the above getAll method. Just add the call to wait within the for loop.
Copy code The code is as follows:

for (var i = 0; i < json. length; i ) {
chain
.wait(500)
.next(function() {
return get(json.shift())
.addCallback(function(friend) { friends.push(friend); });
});
}

Summary
Through some simple examples, we learned about Async. Common ways to use Operation, and how to extend its functionality when necessary. I hope Async.Operation can effectively help everyone improve the code readability of Ajax applications.
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn