Ajax请求等待执行另一个ajax请求

时间:2018-01-11 01:36:22

标签: javascript php jquery ajax

我正在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);
                }
            }
        }
    });

}

我想知道如何在不等待其他请求的情况下发送请求

3 个答案:

答案 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);
        });
    });
}

注意:

  1. 有关详细说明,请参阅代码中的注释
  2. 使用jQuery.ajax timeout:选项更简单,但Firefox 3.0+中的限制使得该方法非常规。
  3. 没有IE版本(据报道)包含本机Promise。