如何进行递归的Promise调用以减少Javascript的收益?

时间:2019-06-23 04:15:50

标签: javascript es6-promise

我正在尝试在JS的Promise内创建递归reduce调用。我的系统在这里的目标是对reduce播放的数组中的每个项目进行n次大调用,然后,如果在该reduce内该大调用决定在获得它之前需要n次小调用回到大项目,则reduce不应跳到下一项,而要等它完成。

我当前的代码是:

function download_preliminary_files_1() {
    let demo_schema_download = new Base_Ajax_Requester(
        localized_data.ajax_url,
        {
            'ajax_action': 'download_demo_file_schema',
            'ajax_nonce': localized_data.ajax_nonce,
            'backend': {
                'data_handle': 'download_demo_file_schema_data',
                'data':
                    {
                        'demo_handle' : 'demo-2',
                    }
            }
        }
    );

    let import_files_download = demo_schema_download.call().then(function() {
        fake_data.steps_to_import.reduce(function(previous_promise, next_step_identifier) {
            return previous_promise.then(function() {
                let file_download = download_demo_file({
                    'demo_handle' : 'demo-2',
                    'step' : next_step_identifier
                }).call();

                file_download.then(function(response) {
                    /**
                     * Here, if I detect that response.remaining_number_of_files > 0, I should start
                     * a chain that keeps calling `download_demo_file` with new parameters.
                     *
                     * Then, when this chain is done, resume the normal reduce behavior.
                     */
                });
            });
        }, Promise.resolve())
    }).catch(function(error) {
        console.log( 'Got this error:' + error);
    });

    return import_files_download;
}

Base_Ajax_Requester是一个帮助程序类,用于处理AJAX请求并在完成后返回一个Promise,以便可以在其周围编写代码。

我的fake_data是:

let fake_data = {
    'demo_handle' : 'demo-2',
    'steps_to_import' : [ 'elementor-hf','post', 'nav_menu' ]
}

如您所见,fake_data.steps_to_import.reduce(..将经历这三个值,对于每个值调用download_demo_file,等待其完成,然后继续下一个。我们可以说我想在elementor-hfpost之间有n个较小的电话。

在此可以看到对download_demo_file的初始调用,这总是从后端返回的:

{
    'message' : '...',
    'file_number' : 1, //Which -n.xml file has been downloaded where n is this number.
    'remaining_number_of_files' : 1 //Calculates, based on what file was downloaded how many files are left. The system knows internally how many files it has to download.
}

再次使用download_demo_file进行重试调用看起来像:

{
    'demo_handle' : 'demo-2',
    'step' : next_step_identifier,
    'file_counter' : 2 //Dynamic. This will signal that it needs to now download file-2.xml.
}

...等等,直到后端发送remaining_number_of_files : 0,然后一切都停止了,因为没有更多文件可下载,并且可以跳到下一个大调用。

我该如何实现?

1 个答案:

答案 0 :(得分:1)

在每个reduce回调中,我将创建一个调用download_demo_file(带有变化的file_counter)的函数,然后Promise解析后,如果{ {1}}。这将意味着remaining_number_of_files > 0将不断地自我调用,直到不再满足getProm()条件为止,这之后,该特定remaining_number_of_files > 0迭代的整个Promise才得以解决。

reduce

使用let import_files_download = demo_schema_download.call().then(function() { fake_data.steps_to_import.reduce(function(previous_promise, step) { let file_counter = 1; return previous_promise.then(function() { const getProm = () => download_demo_file({ demo_handle: 'demo-2', step, file_counter }).call() .then((response) => { file_counter++; return response.remaining_number_of_files > 0 ? getProm() : response }); return getProm(); }); }, Promise.resolve()) }).catch(function(error) { console.log('Got this error:' + error); }); / async可能更容易阅读和理解很多代码,

await

捕获异步函数的使用者。