[英]Ajax Request waiting another ajax request to be executed
我正在用PhP开发聊天,并且正在进行长时间轮询以检查服务器上的新消息。 在Ajax请求中进行长时间轮询时,如果服务器有新的注册消息,则服务器最多检查25秒。 在服务器到达的那段时间内,它不会向javascript返回任何内容,如果我发送了新请求,浏览器将等待检查完成以发送新消息
chat.js
function sndmessage(message, idchat) {
if (message != "") {
var $this = $('.chat .msgs');
var indice = 0;
var msg = message;
$('#sendmsg').val("");
$.ajax({
url: "../ajax/sendmessage.ajax.php",
type: "POST",
data: {
"message": msg,
"id": id
},
success: function(response) {
return;
}
});
}
return true;
}
function polling(idm, idu) {
var interval;
$.ajax({
async: true,
url: "../ajax/polling.ajax.php",
data: {
"idm": idm,
"idu": idu
},
type: "POST",
dataType: "JSON",
success: function(response) {
clearInterval(interval);
if (response.response == false) {
interval = setTimeout(function() {
polling(idm, idu);
}, 500);
} else {
if ('id' in response[0][0]) {
for (var i = 0; i < response[0].length; i++) {
if (mensagensIDs.indexOf(response[0][i]['id']) < 0) {
mensagensIDs.push(response[0][i]['id']);
let data = response[0][i]['data'].split(" "),
dia = data[0].split("-").reverse().join().replaceAll(",", "/"),
hora = data[1].split(":").slice(0, 2).join(":"),
mensagem = response[0][i]['mensagem'],
remetente = (response[0][i]['remetente'].indexOf(" - ") > 0) ? "admin" : "usuario",
destinatario = (response[0][i]['destinatario'].indexOf(" - ") > 0) ? "admin" : "usuario",
id = response[0][i]['id'];
let d = new Date();
let html = (d.getDate() == dia.split("/")[0]) ? hora : dia + " - " + hora;
chats.push({
"idu": idu,
"chat": {
"id": id,
"class": (remetente == "admin") ? "msg-adm teal lighten-1" : "msg-eu",
"class2": (remetente == "admin") ? "white-text" : "blue-text text-darken-2",
"msg": mensagem,
"tooltip": html,
"tooltippos": (remetente == "admin") ? "right" : "left"
}
});
if (idu == chatatual) {
$('.chat .msgs').append('<div id="' + idu + '" class="col s12">\
<div class="' + ((remetente == "admin") ? "msg-adm teal lighten-1" : "msg-eu") + ' z-depth-1">\
<span class="tooltipped pointer ' + ((remetente == "admin") ? "white-text" : "blue-text text-darken-2") + '" data-position="' + ((remetente == "admin") ? "right" : "left") + '" data-delay="50" data-tooltip="' + html + '">' + mensagem + '</span>\
</div>\
</div>').animate({
scrollTop: $('.msgs').prop("scrollHeight")
}, 500);
} else {
$('li.collection-item.avatar#' + idu).find('.badge').text("New message");
}
}
}
interval = setTimeout(function() {
polling(mensagensIDs[mensagensIDs.length - 1], idu);
}, 500);
} else {
interval = setTimeout(function() {
polling(idm, idu);
}, 5000);
}
}
}
});
}
我想知道如何发送请求而不等待其他请求
实际上很简单。 您正在做的是发送请求,并在收到响应时调用下一个循环 ,这不是您想要的。 您应该执行的操作如下:
function polling(idm,idu){
var interval;
$.ajax({/*do your stuff here*/});
setTimeout(function(){pooling(/*whatever*/)}, 500); // See that this is outside the ajax call, so it doesn't wait for the response
}
为什么不将ajax中的两个“异步”都设置为true? 您可以发送第二个ajax,而无需等待第一个。
$.ajax({
'async': true,
//your code
})
这里的关键是要了解:
jQuery.ajax()
返回一个promise。 jQuery.ajax()
返回的承诺与保证在25000毫秒后拒绝的承诺进行竞争来实现的。 现在,有两种编写代码的方法(有关说明,请参见脚注2)
始终使用jQuery Promise
前两个实用程序功能:
// a promise-returning `delay()` utility, which is the only place that `setTimeout()` is used.
function delay(t) {
return new jQuery.Deferred(function(dfrd) {
setTimeout(dfrd.resolve, t);
}).promise();
}
// a promise-returning `race()` utility which ensures that the first promise in `promises` to resolve/reject will resolve/reject the returned promise.
function race(promises) {
return new jQuery.Deferred(function(dfrd) {
promises.forEach(function(p) {
p.then(function(result) {
dfrd.resolve(result);
}, function(reason) {
dfrd.reject(reason);
});
});
}).promise();
}
现在, polling()
function polling(idm, idu) {
// first promise
var ajaxPromise = $.ajax({
'async': true,
'url': '../ajax/polling.ajax.php',
'data': { 'idm': idm, 'idu': idu },
'type': 'POST',
'dataType': 'JSON',
}).then(function(response) {
if (response.response && ('id' in response[0][0])) {
// ... lots of synchronous processing ...
return [mensagensIDs[mensagensIDs.length - 1], idu]; // or maybe `return [mensagensIDs.pop(), idu]`?
} else {
return [idm, idu];
}
});
// second promise
var timeoutPromise = delay(25000).then(function() {
return new jQuery.Deferred().reject(new Error('long-poll-timeout')).promise();
});
// Now the clever bit ...
// At this point you have two promises, which can be raced against each other.
// Exactly what happens next, depends on who wins the race.
// * if `timeoutPromise` wins the race, it will be caught below, the ajax will be aborted, then execution will progress to the second chained `.then()`.
// * if `ajaxPromise` wins the race, then the `.catch()` clause will be bypassed, and execution will progress directly to the second chained `.then()`.
return race([ajaxPromise, timeoutPromise])
.then(null, function(error) { // this is effectively a `.catch()` block.
console.log(error.message); // you will see 'long-poll-timeout' (or possibly some ajax/http error message).
ajaxPromise.abort(); // ensure that `ajaxPromise` **doesn't** follow its success path.
return [idm, idu]; // deliver `[idm, idu]` to the chained .then().
})
.then(function(args) { // via one route or other, `[idm, idu]` or `[mensagensIDs[mensagensIDs.length - 1], idu]` is delivered here as `args`.
return delay(500).then(function() {
return polling.apply(null, args);
});
});
}
使用jQuery.ajax()和javascript本机Promises
首先,一个实用程序功能:
// a promise-returning `delay()` utility, which is the only place that `setTimeout()` is used.
function delay(t) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, t);
});
}
现在, polling()
function polling(idm, idu) {
// first promise
var ajaxPromise = $.ajax({
'async': true,
'url': '../ajax/polling.ajax.php',
'data': { 'idm': idm, 'idu': idu },
'type': 'POST',
'dataType': 'JSON',
}).then(function(response) {
if (response.response && ('id' in response[0][0])) {
// ... lots of synchronous processing ...
return [mensagensIDs[mensagensIDs.length - 1], idu]; // or maybe `return [mensagensIDs.pop(), idu]`?
} else {
return [idm, idu];
}
});
// second promise
var timeoutPromise = delay(25000).then(function() {
return Promise.reject(new Error('long-poll-timeout'));
});
// Now the clever bit ...
// At this point you have two promises, which can be raced against each other.
// Exactly what happens next, depends on who wins the race.
// * if `timeoutPromise` wins the race, it will be caught below, the ajax will be aborted, then execution will progress to the chained `.then()`.
// * if `ajaxPromise` wins the race, then the `.catch()` clause will be bypassed, and execution will progress directly to the chained `.then()`.
return Promise.race([ajaxPromise, timeoutPromise])
.catch(function(error) {
console.log(error.message); // you will see 'long-poll-timeout' (or possibly some ajax/http error message).
ajaxPromise.abort(); // ensure that `ajaxPromise` **doesn't** follow its success path.
return [idm, idu]; // deliver `[idm, idu]` to the chained .then().
})
.then(function(args) { // via one route or other, `[idm, idu]` or `[mensagensIDs[mensagensIDs.length - 1], idu]` is delivered here as `args`.
return delay(500).then(function() {
return polling.apply(null, args);
});
});
}
笔记:
timeout:
选项甚至更简单,但是Firefox 3.0+中的约束使该方法成为非通用的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.