jQuery가 비동기식 Ajax 요청보다는 동기식을 수행하도록하려면 어떻게해야합니까?
-
02-07-2019 - |
문제
표준 확장 지점을 제공하는 JavaScript 위젯이 있습니다. 그들 중 하나는 beforecreate
기능. 돌아와야합니다 false
항목이 생성되는 것을 방지합니다.
jQuery를 사용 하여이 기능에 AJAX 호출을 추가했습니다.
beforecreate: function (node, targetNode, type, to) {
jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),
function (result) {
if (result.isOk == false)
alert(result.message);
});
}
하지만 위젯이 아이템을 만들지 못하게하고 싶으므로 돌아와야합니다. false
콜백이 아닌 어머니 기능에서. jQuery 또는 다른 브라우저 API를 사용하여 동기식 AJAX 요청을 수행하는 방법이 있습니까?
해결책
로부터 jQuery 문서: 당신은 그것을 지정합니다 비동기 옵션 거짓 동기식 Ajax 요청을 받으려면. 그런 다음 콜백이 어머니 기능이 진행되기 전에 일부 데이터를 설정할 수 있습니다.
제안 된대로 변경하면 코드가 어떻게 보이는지는 다음과 같습니다.
beforecreate: function (node, targetNode, type, to) {
jQuery.ajax({
url: 'http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),
success: function (result) {
if (result.isOk == false) alert(result.message);
},
async: false
});
}
다른 팁
전화하여 jQuery의 Ajax 설정을 동기 모드로 넣을 수 있습니다.
jQuery.ajaxSetup({async:false});
그런 다음 Ajax 통화를 사용하여 수행하십시오 jQuery.get( ... );
그런 다음 다시 한 번 켜십시오
jQuery.ajaxSetup({async:true});
@adam의 제안과 똑같은 일을하지만, 재구성하고 싶은 사람에게 도움이 될 수 있습니다. jQuery.get()
또는 jQuery.post()
더 정교한 사람에게 jQuery.ajax()
통사론.
훌륭한 솔루션! 성공 조항에서 값을 반환하면 정의되지 않은 것으로 돌아 왔다는 것을 알았습니다. 변수에 저장하고 그 변수를 반환해야했습니다. 이것은 내가 생각해 낸 방법입니다.
function getWhatever() {
// strUrl is whatever URL you need to call
var strUrl = "", strReturn = "";
jQuery.ajax({
url: strUrl,
success: function(html) {
strReturn = html;
},
async:false
});
return strReturn;
}
이 모든 대답은 Async와 함께 Ajax 호출을 수행하면 Ajax 요청이 완료 될 때까지 브라우저가 매달릴 것입니다. Flow Control 라이브러리를 사용하면 브라우저를 끊지 않고이 문제를 해결합니다. 다음은 다음과 같은 예입니다 frame.js:
beforecreate: function(node,targetNode,type,to) {
Frame(function(next)){
jQuery.get('http://example.com/catalog/create/', next);
});
Frame(function(next, response)){
alert(response);
next();
});
Frame.init();
}
function getURL(url){
return $.ajax({
type: "GET",
url: url,
cache: false,
async: false
}).responseText;
}
//example use
var msg=getURL("message.php");
alert(msg);
크로스 도메인 Ajax 전화를하는 경우 (사용하여 JSONP) - 너 캔트 동기식으로, async
깃발은 jQuery에 의해 무시됩니다.
$.ajax({
url: "testserver.php",
dataType: 'jsonp', // jsonp
async: false //IGNORED!!
});
JSONP-CALL의 경우 사용할 수 있습니다.
참고 : 사용해서는 안됩니다 async: false
이 경고 메시지로 인해 :
Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / Seamonkey 2.27)으로 시작하여 메인 스레드의 동기 요청은 사용자 경험의 부정적인 영향으로 인해 더 이상 사용되지 않았습니다.
크롬은 심지어 콘솔에서 이것에 대해 경고합니다.
기본 스레드의 동기식 XMLHTTPREQUEST는 최종 사용자의 경험에 해로운 영향을 미치기 때문에 더 이상 사용되지 않습니다. 더 많은 도움을 받으려면 확인하십시오 https://xhr.spec.whatwg.org/.
이렇게하면 어느 날 작동을 멈출 수 있기 때문에 이와 같은 일을하고 있다면 페이지를 끊을 수 있습니다.
동기식이지만 여전히 차단하지 않는 경우에도 여전히 느끼는 방식을 원한다면 Async/Await을 사용해야하며 아마도 새로운 약속을 기반으로하는 일부 Ajax를 사용해야합니다. 술책 API
async function foo() {
var res = await fetch(url)
console.log(res.ok)
var json = await res.json()
console.log(json)
}
편집하다크롬은 작업 중입니다 페이지 해고에서 XHR 동기화를 허용하지 않습니다 페이지를 탐색하거나 사용자가 닫을 때. 여기에는 전, 언로드, 페이지 리드 및 가시성이 포함됩니다.
이것이 당신의 유스 케이스라면 당신은 Navigator.SendBeacon 대신에
페이지가 HTTP 헤더 또는 iframe의 허용 속성으로 동기화를 비활성화 할 수도 있습니다.
와 함께 async: false
당신은 차단 된 브라우저를 얻습니다. 비 차단 동기식 솔루션의 경우 다음을 사용할 수 있습니다.
ES6/ECMAScript2015
ES6을 사용하면 생성기 및 the를 사용할 수 있습니다 공동 도서관:
beforecreate: function (node, targetNode, type, to) {
co(function*(){
let result = yield jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value));
//Just use the result here
});
}
ES7
ES7을 사용하면 ASYC를 기다릴 수 있습니다.
beforecreate: function (node, targetNode, type, to) {
(async function(){
let result = await jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value));
//Just use the result here
})();
}
Carcione의 답을 사용하여 JSON을 사용하도록 수정했습니다.
function getUrlJsonSync(url){
var jqxhr = $.ajax({
type: "GET",
url: url,
dataType: 'json',
cache: false,
async: false
});
// 'async' has to be 'false' for this to work
var response = {valid: jqxhr.statusText, data: jqxhr.responseJSON};
return response;
}
function testGetUrlJsonSync()
{
var reply = getUrlJsonSync("myurl");
if (reply.valid == 'OK')
{
console.dir(reply.data);
}
else
{
alert('not valid');
}
}
나는 그것을 추가했다 데이터 형식 의 'JSON' 그리고 .RESPONSETEXT 에게 ResponseJson.
나는 또한 그것을 사용하여 상태를 검색했습니다 statustext 반환 된 객체의 속성. 이것은 JSON이 유효한지 여부가 아니라 Ajax 응답의 상태입니다.
백엔드는 응답을 올바른 (잘 형성된) JSON으로 반환해야합니다. 그렇지 않으면 반환 된 객체가 정의되지 않습니다.
원래 질문에 대답 할 때 고려해야 할 두 가지 측면이 있습니다. 하나는 Ajax에게 동기식으로 수행하도록 지시하고 있습니다 (설정하여 비동기 : 거짓) 그리고 다른 하나는 콜백 함수가 아닌 호출 함수의 반환 문을 통해 응답을 반환합니다.
나는 또한 포스트와 함께 그것을 시도했고 그것은 효과가 있었다.
게시물을 게시하고 추가했습니다 데이터 : postdata
function postUrlJsonSync(url, postdata){
var jqxhr = $.ajax({
type: "POST",
url: url,
data: postdata,
dataType: 'json',
cache: false,
async: false
});
// 'async' has to be 'false' for this to work
var response = {valid: jqxhr.statusText, data: jqxhr.responseJSON};
return response;
}
위의 코드는 경우에만 작동합니다. 비동기 ~이다 거짓. 당신이 설정했다면 비동기 : 참 반환 된 개체 JQXHR Ajax 통화가 반환 될 때 유효하지 않을 것입니다. 나중에 비동기 호출이 완료되었을 때만 나중에 응답 변하기 쉬운.
이것은 예입니다 :
$.ajax({
url: "test.html",
async: false
}).done(function(data) {
// Todo something..
}).fail(function(xhr) {
// Todo something..
});
첫째, 우리는 $ .ajax를 사용할 때와 $ .get/$를 사용할 때를 이해해야합니다. post.
요청 헤더 설정, 캐싱 설정, 동기 설정 등과 같은 AJAX 요청에 대한 낮은 레벨 제어가 필요한 경우 $ .ajax로 이동해야합니다.
$ .get/$. post : AJAX 요청에 대한 낮은 레벨 제어가 필요하지 않은 경우, 단순한 데이터를 서버에 가져 오거나 게시합니다.그것은 속기입니다
$.ajax({
url: url,
data: data,
success: success,
dataType: dataType
});
따라서 $ .get/$. post와 함께 다른 기능 (동기화, 캐시 등)을 사용할 수 없습니다.
따라서 AJAX 요청을 통해 저 레벨 제어 (동기화, 캐시 등)의 경우 $ .Ajax로 이동해야합니다.
$.ajax({
type: 'GET',
url: url,
data: data,
success: success,
dataType: dataType,
async:false
});
이것은 jQuery를 사용한 비동기 요청에 대한 간단한 구현입니다. 나는 이것이 누구에게도 도움이되기를 바랍니다.
var queueUrlsForRemove = [
'http://dev-myurl.com/image/1',
'http://dev-myurl.com/image/2',
'http://dev-myurl.com/image/3',
];
var queueImagesDelete = function(){
deleteImage( queueUrlsForRemove.splice(0,1), function(){
if (queueUrlsForRemove.length > 0) {
queueImagesDelete();
}
});
}
var deleteImage = function(url, callback) {
$.ajax({
url: url,
method: 'DELETE'
}).done(function(response){
typeof(callback) == 'function' ? callback(response) : null;
});
}
queueImagesDelete();
왜냐하면 XMLHttpReponse
동기 작업이 감가 상각됩니다. XMLHttpRequest
. 이를 통해 주문 된 Ajax 쿼리는 자연에서 여전히 비열한 일이지만 단일 사용 CSRF 토큰에 매우 유용합니다.
또한 jQuery와 같은 라이브러리가 원활하게 작동 할 수 있습니다.
/* wrap XMLHttpRequest for synchronous operation */
var XHRQueue = [];
var _XMLHttpRequest = XMLHttpRequest;
XMLHttpRequest = function()
{
var xhr = new _XMLHttpRequest();
var _send = xhr.send;
xhr.send = function()
{
/* queue the request, and if it's the first, process it */
XHRQueue.push([this, arguments]);
if (XHRQueue.length == 1)
this.processQueue();
};
xhr.processQueue = function()
{
var call = XHRQueue[0];
var xhr = call[0];
var args = call[1];
/* you could also set a CSRF token header here */
/* send the request */
_send.apply(xhr, args);
};
xhr.addEventListener('load', function(e)
{
/* you could also retrieve a CSRF token header here */
/* remove the completed request and if there is more, trigger the next */
XHRQueue.shift();
if (XHRQueue.length)
this.processQueue();
});
return xhr;
};
이것은 나의 "실”네임 스페이스 :
var Thread = {
sleep: function(ms) {
var start = Date.now();
while (true) {
var clock = (Date.now() - start);
if (clock >= ms) break;
}
}
};
그리고 이것이 내가 그것을 부르는 방법입니다.
var d1 = new Date();
console.log('start ' + d1.toLocaleTimeString());
Thread.sleep(10000);
var d2 = new Date();
console.log('end ' + d2.toLocaleTimeString());
콘솔을 보면 다음과 같은 결과를 얻을 수 있습니다.
start 1:41:21 PM
end 1:41:31 PM