繁体   English   中英

Ajax请求正在等待另一个Ajax请求被执行

[英]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);
        });
    });
}

笔记:

  1. 有关详细说明,请参见代码中的注释
  2. 使用jQuery.ajax的timeout:选项甚至更简单,但是Firefox 3.0+中的约束使该方法成为非通用的。
  3. IE的任何版本(据报道)均不包含本地Promises。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM