首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何进行递归承诺调用,使其返回Javascript中的reduce?

我如何进行递归承诺调用,使其返回Javascript中的reduce?
EN

Stack Overflow用户
提问于 2019-06-23 04:15:50
回答 1查看 42关注 0票数 1

我试图在JS中的Promise中创建一个递归的reduce调用。我这里的系统的目标是对reduce播放的数组中的每一项进行n个大调用,然后,如果在reduce内部,那个大调用决定在返回大调用之前需要n个较小的调用,那么reduce不应该跳到下一个条目,只需要等待它完成。

我目前的代码是:

代码语言:javascript
复制
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是:

代码语言:javascript
复制
let fake_data = {
    'demo_handle' : 'demo-2',
    'steps_to_import' : [ 'elementor-hf','post', 'nav_menu' ]
}

正如您所看到的,fake_data.steps_to_import.reduce(..将遍历这3个值,因为每个值都调用download_demo_file,等待它完成,然后继续到下一个值。我们可以说,我希望,在elementor-hfpost之间有一个较小的电话。

download_demo_file的初始调用出现在上面,下面是从后端返回的内容:

代码语言:javascript
复制
{
    '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进行重试调用,如下所示:

代码语言:javascript
复制
{
    'demo_handle' : 'demo-2',
    'step' : next_step_identifier,
    'file_counter' : 2 //Dynamic. This will signal that it needs to now download file-2.xml.
}

...and是这样的,直到后端发送remaining_number_of_files : 0,然后一切都停止了,因为没有更多的文件要下载,而且它可以跳到下一个大调用。

我怎样才能做到这一点?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-23 04:22:12

在每个reduce回调中,我都会创建一个函数来调用download_demo_file (通过一个不断变化的file_counter),在这个承诺解决之后,递归地返回一个调用,如果是remaining_number_of_files > 0。这将意味着getProm()将不断地调用自己,直到remaining_number_of_files > 0条件不再满足为止,并且只有在此之后,对特定reduce迭代的整个承诺才会得到解决。

代码语言:javascript
复制
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来阅读和理解代码可能要容易得多:

代码语言:javascript
复制
await demo_schema_download.call();
const import_files_download = [];
for (const step of fake_data.steps_to_import) {
  let response;
  let file_counter = 1;
  do {
    response = await download_demo_file({
      demo_handle: 'demo-2',
      step,
      file_counter
    }).call();
    file_counter++;
  } while (response.remaining_number_of_files > 0);
  import_files_download.push(response); // is this needed?
}
return import_files_download; // is this needed?

在异步函数的使用者中捕获。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56720953

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档