Use Promise to solve code nesting problems caused by multiple asynchronous Ajax requests (perfect solution), promiseajax
Problem
When the front-end students made pages, they made a common mistake: they wrote down multiple Ajax requests in sequence, while the subsequent requests returned results for the previous requests, yes. The following code is used:
Var someData; $. ajax ({url: '/prefix/entity1/action1', type: 'get', async: true, contentType: "application/json", success: function (resp) {// do something on response someData. attr1 = resp. attr1 ;}, error: function (XMLHttpRequest, textStatus, errorThrown) {// on this page, all request errors are processed in the same way if (XMLHttpRequest. status = "401") {window. location. href = '/login.html';} else {alert (XMLHttpRequest. responseText) ;}}}); $. ajax ({url: '/prefix/entity2/action2', type: 'post', dataType: "json", data: JSON. stringify (someData), async: true, contentType: "application/json", success: function (resp) {// do something on response}, error: function (XMLHttpRequest, textStatus, errorThrown) {// on this page, all request errors are processed the same if (XMLHttpRequest. status = "401") {window. location. href = '/login.html';} else {alert (XMLHttpRequest. responseText );}}});
The above code has two problems:
* The execution sequence is not guaranteed. action2 may be issued before action1 returns, resulting in the failure to pass the someData. attr1 parameter correctly.
* The code of the two ajax requests is very duplicated.
Ideas
- The problem of code duplication is relatively well solved, especially in your own projects, various parameters can be fixed through the standard, it is better to encapsulate an ajax method with fewer parameters.
// Url: Address // data: data object, which is converted into a json string in the function. If the string is not transmitted, the GET method is used. If the string is uploaded, function ajax (url, data, callback) using the POST method {$. ajax ({url: url, type: data = null? 'Get': 'post', dataType: "json", data: data = null? '': JSON. stringify (data), async: true, contentType: "application/json", success: function (resp) {callback (resp) ;}, error: function (XMLHttpRequest, textStatus, errorThrown) {if (XMLHttpRequest. status = "401") {window. parent. location = '/enterprise/enterprise_login.html'; self. location = '/enterprise/enterprise_login.html';} else {alert (XMLHttpRequest. responseText );}}});}
In this case, only the url, data, and callback parameters are required. The rest are fixed.
- For execution sequence problems, you can put the second request in the callback of the first request, as shown in the following figure:
ajax('/prefix/entity1/action1',null, function(resp){ //do something on response someData.attr1 = resp.attr1; ajax('/prefix/entity2/action2', someData, function(resp){ //do something on response }};
At this point, the problem seems to have been solved perfectly, but we can imagine that if there are more than two requests, but four or five, at the same time, there are other asynchronous operations (such as the initialization of Vue objects in our page), which are dependent on each other. Just like this, the stacked parentheses are nested, which makes people dizzy.
You need to find a way to make the expression of asynchronous calls look like synchronous calls.
Just recently I read a book about ES6 by instructor Ruan Yifeng, and the user does not have strong requirements for compatibility with IE browsers, so I chose Promise.
Solution
In fact, modern browsers have built-in support for Promise, and no third-party libraries are required. Only Internet Explorer does not work.
- Modify the ajax encapsulation function, call resolve () upon success, call reject () Upon failure, and return the Promise object
function ajax(url, data, callback) { var p = new Promise(function (resolve, reject) { $.ajax({ url: url, type: data == null ? 'GET' : 'POST', dataType: "json", data: data == null ? '' : JSON.stringify(data), async: true, contentType: "application/json", success: function (resp) { callback(resp); resolve(); }, error: function (XMLHttpRequest, textStatus, errorThrown) { if (XMLHttpRequest.status == "401") { window.parent.location = '/enterprise/enterprise_login.html'; self.location = '/enterprise/enterprise_login.html'; } else { alert(XMLHttpRequest.responseText); } reject(); } }); }); return p;}
ajax('/prefix/entity1/action1',null, function(resp){ //do something on response someData.attr1 = resp.attr1;}).then( ajax('/prefix/entity2/action2', someData, function(resp){ //do something on response }).then( initVue() ;).then( //do something else)
The above section describes how to use Promise to solve code nesting problems caused by multiple asynchronous Ajax requests (perfect solution). I hope it will be helpful to you, if you have any questions, please leave a message and the editor will reply to you in time. Thank you very much for your support for the help House website!