Home  >  Article  >  Web Front-end  >  Use Promise to solve code nesting problems caused by multiple asynchronous Ajax requests

Use Promise to solve code nesting problems caused by multiple asynchronous Ajax requests

亚连
亚连Original
2018-05-22 16:37:461621browse

This article mainly introduces the use of Promise to solve the code nesting problem caused by multiple asynchronous Ajax requests. Friends in need can refer to

Questions

When the front-end students were making pages, they made a common mistake: writing down multiple Ajax requests in sequence, and subsequent requests are dependent on the return results of the previous requests. 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 very likely It was issued before action1 returned, resulting in the parameter someData.attr1 not being transmitted correctly

*Secondly, the code duplication of the two ajax requests was 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 and encapsulated an ajax method with fewer parameters. That’s fine

//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);
        }
      }
    });
}

This way only the three necessary parameters of url, data and callback need to be filled in, and the others are fixed

  • Regarding the execution order, you can put the second request in the callback of the first request, in the form:

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 more than two requests, but 4 or 5, and there are other asynchronous operations (such as Vue objects in our page Initialization), there are dependencies between each other. Just such layers of nested brackets can make people dizzy.

We need to find a way to make the expression of asynchronous calls look like synchronous calls.

I happened to read Teacher 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, and there is no need for third-party libraries No, only IE doesn't work, so I gave up

  • Modify the ajax wrapper function, call resolve() when successful, call reject() when failed, 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;
}

  • Modify the calling end

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 is what I compiled for everyone. I hope it will be helpful to everyone in the future.

Related articles:

HTTP messages and basic knowledge of ajax

The principle of Ajax cross-domain request (graphic tutorial)

Ajax asynchronous request technology example explanation

The above is the detailed content of Use Promise to solve code nesting problems caused by multiple asynchronous Ajax requests. For more information, please follow other related articles on the PHP Chinese website!

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