This time I will show you how to solve the code nesting caused by multiple asynchronous Ajax requests. What are the precautions . Here are practical cases. Let’s take a look.
Question
When the front-end students made the page, they made a common mistake: writing down multiple Ajax requests in sequence , and subsequent requests are dependent on the return result of the previous request. As shown in the following code:
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) { //在这个页面里,所有的请求的错误都做同样的处理 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) { //在这个页面里,所有的请求的错误都做同样的处理 if (XMLHttpRequest.status == "401") { window.location.href = '/login.html'; } else { alert(XMLHttpRequest.responseText); } } });
The above code has two problems:
*The first is that the execution order cannot be guaranteed. Action2 is likely to be issued before action1 returns, resulting in someData.attr1 This parameter was not transmitted correctly
*Secondly, the code duplication of the two ajax requests is very serious
Thinking
The problem of code duplication is relatively easy to solve, especially in your own project. Various parameters can be determined through specifications. Just encapsulate an ajax method with fewer parameters
//url:地址 //data:数据对象,在函数内部会转化成json串,如果没传,表示用GET方法,如果传了,表示用POST方法 function ajax(url, data, callback) { $.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 way, only the three necessary parameters of url, data and callback need to be filled in, and the others are fixed.
As for the execution order, you can put the second request in the first In the callback of a request, it looks like:
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 } };
So far the problem seems to be solved perfectly, but it is conceivable that if there are not only two requests, but 4 or 5, and at the same time There are other asynchronous operations (such as the initialization of the Vue object in our page), which are dependent on each other. Just the layers of nested brackets are already dizzying.
We need to find a way to make the expression of asynchronous calls look like synchronous calls.
I happened to read Mr. Ruan Yifeng’s book about ES6 recently, and the user did not insist on compatibility with IE browser, so I chose the Promise solution
Solution
Introducing Promise
In fact, modern browsers already have built-in support for Promise. No third-party libraries are needed anymore, only IE doesn't work, so I gave up
Transform the ajax wrapper function, call resolve() when successful, call reject() when failed, and return 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; }
Modify the caller
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 )
I believe you have mastered the method after reading the case in this article, more Please pay attention to other related articles on the php Chinese website!
Recommended reading:
How to communicate data between C and View
Ajax interaction was reported with status=parsererror How to solve the error
The above is the detailed content of How to solve code nesting caused by multiple asynchronous Ajax requests. For more information, please follow other related articles on the PHP Chinese website!