이 글에서는 다중 비동기 Ajax 요청으로 인해 발생하는 코드 중첩 문제를 해결하기 위해 Promise를 사용하는 방법을 주로 소개합니다. 도움이 필요한 친구들이 참고할 수 있습니다.
Problem
프론트엔드 학생들이 페이지를 만들 때, 일반적인 실수 오류: 여러 Ajax 요청이 순차적으로 기록되고 후속 요청은 이전 요청의 반환 결과에 따라 달라집니다. 다음 코드에서 볼 수 있듯이
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); } } });
위 코드에는 두 가지 문제가 있습니다.
*첫째, action1이 반환되기 전에 Action2가 실행될 가능성이 높으며, 이로 인해 someData.attr1 매개변수가 발생합니다. 실패했습니다. 올바르게 전송되었습니다
* 둘째, 두 Ajax 요청의 코드 중복이 매우 심각합니다.
아이디어
코드 중복 문제는 특히 자신의 프로젝트에서 다양한 매개변수로 해결하기가 상대적으로 쉽습니다. 사양을 통해 결정 가능 젠장, 그냥 더 적은 수의 매개변수로 ajax 메소드를 캡슐화하면 됩니다
//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); } } }); }
이렇게 하면 url, data, callback의 필수 매개변수 3개만 채워넣고 나머지는 고정되어 있습니다.
실행 순서 문제는 첫 번째 요청의 콜백에 두 번째 요청을 다음 형식으로 넣을 수 있습니다.
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 } };
지금까지 문제는 완벽하게 해결된 것 같지만 3개 이상의 요청이 있지만 4, 5개가 있고 서로 의존하는 다른 비동기 작업(예: 페이지의 Vue 개체 초기화)도 있는 경우 이러한 중첩된 괄호 레이어가 있을 수 있습니다. 사람들을 어지럽게 만듭니다.
비동기 호출 표현을 동기 호출처럼 보이게 만드는 방법을 찾아야 합니다.
최근 ES6에 관한 Ruan Yifeng 선생님의 책을 읽었는데, 사용자들이 IE 브라우저와의 호환성을 고집하지 않아서 Promise 솔루션을 선택했습니다
Solution
Introducing Promise
사실, 최신 브라우저에는 이미 Promise 지원 기능이 내장되어 있습니다. 심지어 IE에서만 이를 수행할 수 없습니다. 저는 포기하고 ajax 래퍼 기능을 변형했습니다. Resolve()를 호출하고 실패하면 Reject()를 호출하고 Promise 객체를 반환합니다
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 )
위는 제가 컴파일한 것입니다 모두를 위해. 앞으로 모든 사람에게 도움이 되기를 바랍니다.
관련 기사:
HTTP 메시지와 ajax에 대한 기본 지식
위 내용은 Promise를 사용하여 여러 비동기 Ajax 요청으로 인한 코드 중첩 문제 해결의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!