javascript - 如何进行递归 Promise 调用以作为 Javascript 中减少的返回?
问题描述
我正在尝试在 JS中创建一个递归Promise
调用。reduce
我的系统在这里的目标是对数组中的每个项目进行 n 次大调用reduce
,然后,如果在其中reduce
那个大调用决定它需要 n 个较小的调用才能返回到大的调用,那么reduce
应该' t 跳到下一个项目,等待它完成。
我目前的代码是:
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(..
,将遍历这 3 个值,对于它们中的每一个 call download_demo_file
,等待它完成,然后继续下一个。我们可以说我想在之间elementor-hf
和之间post
进行 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
,然后一切都停止了,因为没有更多文件要下载,它可以跳到下一个大调用。
我怎样才能做到这一点?
解决方案
在每个reduce
回调中,我会创建一个调用download_demo_file
(使用更改file_counter
)的函数,然后在 Promise 解决之后,递归返回对自身的调用 if remaining_number_of_files > 0
。这将意味着getProm()
它将不断地调用自己,直到remaining_number_of_files > 0
不再满足条件,并且只有在那之后,该特定reduce
迭代的整个 Promise 才会解决。
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
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?
捕获异步函数的使用者。
推荐阅读
- python - 从 Python 中的给定元素形成所有可能的唯一 3 位数字组合,
- node.js - 如何将“Access-Control-Allow-Origin”标头设置为仅允许一台特定计算机
- javascript - 为什么 WebGL 实例化扩展只绘制一个三角形而不是两个?
- bulma - 使用 CDN 时,Bulma 可折叠不工作
- c - 堆地址减少,增加
- javafx - 如何在 JAVAFX 中创建“添加标签”按钮?
- autodesk-forge - 如何在锻造中获取点击对象(机械设备)的 URN?
- angular - 如何使用角度插值作为数组中的索引?
- machine-learning - 如何计算单个 CNN 层中的权重和偏差值的数量?
- c# - MongoDB GroupBy SUM 与 C# 中的过滤器