代码之家  ›  专栏  ›  技术社区  ›  Marcin Nabiałek

等待所有请求完成

  •  2
  • Marcin Nabiałek  · 技术社区  · 8 年前

    我正在执行网站,有两个问题。我正在使用jquery 3。

    1)我正在发送两个ajax请求,如果失败,我需要从这两个请求中获取信息。我正在使用这样的代码:

    let ajaxCalls = [];
    
    if (logoUploaded) {
        const sendPhoto = $.ajax({
            type: submit.data('ajax-logo-create-method').toUpperCase(),
            url: submit.data('ajax-logo-create-url'),
            headers: headers,
            data: {file: logo},
            dataType: 'json',
            success: function (data) {
                // here another request would be run
                sleep(500).then(() => {
                    console.log('was sleeping 500 ms');
                });
                sleep(10000).then(() => {
                    console.log('was sleeping 10000 ms');
                });
            }
        });
        ajaxCalls.push(sendPhoto);
    }
    
    const sendContactData = $.ajax({
        type: submit.data('ajax-data-method').toUpperCase(),
        url: submit.data('ajax-data-url'),
        headers: headers,
        data: data,
        dataType: 'json'
    });
    
    ajaxCalls.push(sendContactData);
    
    $.when.apply(this, ajaxCalls).then(function () {
        hideValidationErrors();
        showSendStatusMessage('#' + submit.data('ajax-update-ok'));
        submit.removeClass('ajax-js-working');
    
    }, function() {
        let validationErrors = [];
        $.each(ajaxCalls, function (index, ajaxCall) {
            if (ajaxCall.status === 422) {
                json = $.parseJSON(ajaxCall.responseText);
                console.log(json);
                $.each(json.errors, function (field, messages) {
                    validationErrors.push({'field': field, 'messages': messages});
                });
            }
        });
    
        hideValidationErrors();
    
        if (validationErrors.length > 0) {
            $.each(validationErrors, function (id, object) {
                wrapper = $('#' + object.field + '-container');
                wrapper.addClass('error');
                displayValidationErrorMessages(wrapper, object.messages);
            });
        }
    
        showSendStatusMessage('#' + submit.data('ajax-update-error'));
        submit.removeClass('ajax-js-working');
    });
    

    但不幸的是,当使用这个代码时 $when .. then 只是在等待第一个失败的请求,我需要他们都在这里。

    2)第二个问题是我在第一个请求中的成功之处。在某些情况下,当此请求完成并成功时,我将不得不运行另一个请求,在这种情况下,我希望运行 $.when.apply(this, ajaxCalls).then(function () { 当成功请求完成时。有可能做到这一点吗?

    如果可能的话,请给我完整的代码示例,我应该做些什么改变。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Marcin Nabiałek    7 年前

    最后,我把数组的开始和完成请求添加到数组中( ajaxCalls doneAjaxCalls 像这样:

    let ajaxCalls = [];
    let doneAjaxCalls = [];
    
    const fileInput = $('img#uploadedImg');
    
    const fileExisted = fileInput.hasClass('imgExisted');
    const fileWasRemoved = fileInput.hasClass('imgDeleted');
    const fileWasUploaded = fileInput.hasClass('newImgUploaded');
    
    const logo = fileInput.attr('src');
    
    const needRemovePhoto = fileExisted && (fileWasRemoved || fileWasUploaded);
    
    if (needRemovePhoto) {
        const removePhoto = $.ajax({
            type: submit.data('ajax-logo-delete-method').toUpperCase(),
            url: submit.data('ajax-logo-delete-url'),
            headers: headers,
            data: {file: logo},
            dataType: 'json',
            error: function (response) {
                doneAjaxCalls.push(response);
                handleMultipleAjaxCalls(submit, ajaxCalls, doneAjaxCalls);
            },
            success: function (response) {
                fileInput.removeClass('imgDeleted');
                fileInput.removeClass('imgExisted');
                if (fileWasUploaded) {
                    const sendPhoto = $.ajax({
                        type: submit.data('ajax-logo-create-method').toUpperCase(),
                        url: submit.data('ajax-logo-create-url'),
                        headers: headers,
                        data: {file: logo},
                        dataType: 'json',
                        success: function (response) {
                            fileInput.addClass('imgExisted');
                        },
                        complete: function (response) {
                            doneAjaxCalls.push(response);
                            handleMultipleAjaxCalls(submit, ajaxCalls, doneAjaxCalls);
                        }
                    });
                }
                else {
                    doneAjaxCalls.push(response);
                    handleMultipleAjaxCalls(submit, ajaxCalls, doneAjaxCalls);
                }
            }
        });
        ajaxCalls.push(removePhoto);
    }
    else if (fileWasUploaded) {
        const sendPhoto = $.ajax({
            type: submit.data('ajax-logo-create-method').toUpperCase(),
            url: submit.data('ajax-logo-create-url'),
            headers: headers,
            data: {file: logo},
            dataType: 'json',
            success: function (response) {
                fileInput.addClass('imgExisted');
            },
            complete: function (response) {
                doneAjaxCalls.push(response);
                handleMultipleAjaxCalls(submit, ajaxCalls, doneAjaxCalls);
            }
        });
        ajaxCalls.push(sendPhoto);
    }
    
    const sendContactData = $.ajax({
        type: submit.data('ajax-method').toUpperCase(),
        url: submit.data('ajax-url'),
        headers: headers,
        data: data,
        dataType: 'json',
        complete: function (response) {
            doneAjaxCalls.push(response);
            handleMultipleAjaxCalls(submit, ajaxCalls, doneAjaxCalls);
        }
    });
    
    ajaxCalls.push(sendContactData);
    

    如你所见,在很多情况下,我会打电话给 handleMultipleAjaxCalls 函数,我这样定义这个函数:

    window.handleMultipleAjaxCalls = function (submit, ajaxCalls, doneAjaxCalls) {
        // if not all expected requests were done (success or failure), do nothing
        if (doneAjaxCalls.length < ajaxCalls.length) {
            return;
        }
    
        // here we know that all expected AJAX requests were completed (success or failure)
    
        // here more logic after all requests are completed
    });
    

    因此,在我执行这个函数的情况下,它可能会发生,逻辑应该被启动,在这个函数中,我比较,如果所有的Ajax调用都真正完成了(仅仅是数组比较的简单长度)