Как я могу использовать «решимость» в моих рекурсивных вызовах AJAX, чтобы я мог использовать «готово»? - PullRequest
0 голосов
/ 11 ноября 2018

Я делаю несколько повторяющихся вызовов AJAX, где я передаю массив от внешнего интерфейса к конечному, и всякий раз, когда он возвращается к внешнему интерфейсу, массив уменьшается (на 1) и, в конечном итоге, быть пустым, поэтому мои рекурсивные вызовы прекратятся.

Вот мои звонки:

function download_required_files(demo_data) {
    var ajaxsecurity = setup_page_params.ajax_nonce;

    jQuery.ajax({
        url: ajaxurl,
        type: 'POST',
        dataType: 'json',
        data: {
            action: 'download_import_files_request',
            security: ajaxsecurity,
            content_install_request_data: JSON.stringify(demo_data),
        },

        success: function (response) {
            console.log(response);
            var data = response.data || false;
            /**
             * If no steps are left, meaning that all required files have been downloaded, proceed with the whole install process.
             */
            if(!data.remaining_steps || !data.remaining_steps.length) {
                return false;
            }

            if(data.can_continue !== 'yes') {
                return false;
            }

            if(data.remaining_steps && data.remaining_steps.length) {
                demo_data.steps_to_take = data.remaining_steps;
                download_required_files(demo_data);

            }

            $('.demo-loader-content').fadeOut();
        },

        error: function (response) {
            $('.demo-loader-content').fadeOut();

        }
    });
}

Если у меня есть 2 шага для загрузки файлов, этот download_required_files будет запущен дважды, тогда это будет сделано, но если я сделаю:

var download_process = download_required_files(demo_data) //Runs 2 times
download_process.done(function() {  //Do stuff here once that function ran 2 times });

Это дает мне ошибку: Cannot read property 'done' of undefined по уважительной причине. То, что download_process не является объектом обещания для этого свойства, просто ... пусто.

Где я должен вмешаться в мой download_required_files, чтобы он сигнализировал внешнему коду: «Эй, в среде обещаний, я закончил!»?

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Это мой подход, отделяющий отдельные запросы AJAX от зацикливания содержимого, а также от обновлений DOM:

function download_one_file(demo_data) {
    return jQuery.ajax({
        url: ajaxurl,
        type: 'POST',
        dataType: 'json',
        data: {
            action: 'download_import_files_request',
            security: setup_page_params.ajax_nonce,
            content_install_request_data: JSON.stringify(demo_data),
        }
    });
}

function download_loop(demo_data) {
    return download_one_file(demo_data).then(function(data) {
        if (!data) {
            return Promise.reject();
        } else if (data.remaining_steps && data.remaining_steps.length) {
            demo_data.steps_to_take = data.remaining_steps;
            return download_loop(demo_data);
        } else {
            return Promise.resolve();
        }
    });
}

function download_required_files(demo_data) {
    return download_loop(demo_data).finally(function() {
        $('.demo-loader-content').fadeOut();
    });
}
0 голосов
/ 11 ноября 2018

Хотя результатом вызова $.ajax является объект jqXHR, подобный обещанию, для того, что вы описываете, я думаю, я бы пошел с вашим собственным собственным обещанием (или Deferred, если хотите) для представления всего рекурсивного процесса:

function download_required_files(demo_data) {
    return new Promise(function(resolve, reject) {
        function worker() {
            var ajaxsecurity = setup_page_params.ajax_nonce;

            jQuery.ajax({
                url: ajaxurl,
                type: 'POST',
                dataType: 'json',
                data: {
                    action: 'download_import_files_request',
                    security: ajaxsecurity,
                    content_install_request_data: JSON.stringify(demo_data),
                },

                success: function (response) {
                    console.log(response);
                    var data = response.data || false;
                    /**
                     * If no steps are left, meaning that all required files have been downloaded, proceed with the whole install process.
                     */
                    if(!data.remaining_steps || !data.remaining_steps.length) {
                        // *** All done
                        $('.demo-loader-content').fadeOut();
                        resolve();
                    } else if(data.can_continue !== 'yes') {
                        // *** All done; but is this an error condition? If so
                        // use `reject` instead of `resolve` below.
                        $('.demo-loader-content').fadeOut();
                        resolve();
                    } else {
                        demo_data.steps_to_take = data.remaining_steps;
                        worker();  // This is the internal recursive call
                    }
                },

                error: function (response) {
                    $('.demo-loader-content').fadeOut();

                }
            });
        }
        worker();
    });
}

Или вместо Deferred:

function download_required_files(demo_data) {
    var d = $.Deferred();

    function worker() {
        var ajaxsecurity = setup_page_params.ajax_nonce;

        jQuery.ajax({
            url: ajaxurl,
            type: 'POST',
            dataType: 'json',
            data: {
                action: 'download_import_files_request',
                security: ajaxsecurity,
                content_install_request_data: JSON.stringify(demo_data),
            },

            success: function (response) {
                console.log(response);
                var data = response.data || false;
                /**
                 * If no steps are left, meaning that all required files have been downloaded, proceed with the whole install process.
                 */
                if(!data.remaining_steps || !data.remaining_steps.length) {
                    // *** All done
                    $('.demo-loader-content').fadeOut();
                    d.resolve();
                } else if(data.can_continue !== 'yes') {
                    // *** All done; but is this an error condition? If so
                    // use `d.reject` instead of `d.resolve` below.
                    $('.demo-loader-content').fadeOut();
                    d.resolve();
                } else {
                    demo_data.steps_to_take = data.remaining_steps;
                    worker();  // This is the internal recursive call
                }
            },

            error: function (response) {
                $('.demo-loader-content').fadeOut();

            }
        });
    }
    worker();
    return d.promise();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...