我正在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);
}
}
}
});
}
我想知道如何在不等待其他请求的情况下发送请求
答案 0 :(得分:0)
实际上非常简单。您正在做的是发送请求,在您收到回复时呼叫下一个循环,这不是您想要的。你应该做的是:
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
}
答案 1 :(得分:0)
为什么不设置&#39; async&#39;在ajax到真?你可以发送第二个ajax而无需等待第一个ajax。
$.ajax({
'async': true,
//your code
})
答案 2 :(得分:0)
在你知道如何使用promises之前,这种事情可能是一场噩梦。
这里的关键是理解:
jQuery.ajax()
返回一个承诺。jQuery.ajax()
返回的承诺与保证在25000 ms后拒绝的承诺相对应来实现的。 现在,有两种方法可以编写代码(请参阅脚注2以获得解释)
在整个
中使用jQuery承诺前两个实用功能:
// 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原生Promise
首先,一个效用函数:
// 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+中的限制使得该方法非常规。