我的职能是遍历多个文件(这些文件将数组中的值用作文件名的构建块)并使用reduce
下载它们。到目前为止,它更像是一种黑客手段,但是Promise
逻辑应该可以工作。
这是我的代码:
function import_demo_files(data) {
/**
* Make a local copy of the passed data.
*/
let request_data = $.extend({}, data);
const get_number_of_files_1 = Promise.resolve({
'data' : {
'number_of_files' : 2
}
});
return new Promise((resolve, reject) => {
let import_files = get_number_of_files_1.then(function(response) {
new Array(response.data.number_of_files).fill(request_data.step_name).reduce((previous_promise, next_step_identifier) => {
let file_counter = 1;
return previous_promise.then((response) => {
if( response !== undefined ) {
if('finished_import' in response.data && response.data.finished_import === true || response.success === false) {
return import_files;
}
}
const recursively_install_step_file = () => import_demo_file({
demo_handle: request_data.demo_handle,
'step_name': request_data.step_name,
'file_counter': file_counter
}).call().then(function(response) {
file_counter++;
if('file_counter' in response.data && 'needs_resume' in response.data) {
if(response.data.needs_resume === true) {
file_counter = response.data.file_counter;
}
}
return response.data.keep_importing_more_files === true ? recursively_install_step_file() : response
});
return recursively_install_step_file();
}).catch(function(error) {
reject(error);
});
}, Promise.resolve())
}).catch(function(error) {
reject(error);
});
resolve(import_files);
});
}
现在,当我这样做时:
const import_call = import_demo_files({ 'demo_handle' : 'demo-2', 'step_name' : 'post' });
console.log(import_call);
console.log
告诉我,import_call
实际上是一个承诺,已经解决。我非常喜欢return
允许我脱离承诺链的方式,但是我不知道如何在其中正确解决我的承诺链,因此很明显,如果没有解决,它会标记为已解决。
我想做import_call.then(...
,但目前还不行,由于import_demo_files
中的处理不当,它在实际执行之前在这里执行了此代码。
答案 0 :(得分:1)
在归约中进行异步递归并不是最简单的事情,并且为什么递归的每次迭代都与其他迭代完全相同,这并不立刻显而易见。
以外部成员的形式删除以下内容后,reduce / recurse模式更易于理解:
1. the `recursively_install_step_file()` function
1. the `new Array(...).fill(...)`, as `starterArray`
1. the object passed repeatedly to `import_demo_file()`, as `importOptions`)
此方法无需使用变量file_counter
,因为importOptions.file_counter
可以直接更新。
function import_demo_files(data) {
// outer members
let request_data = $.extend({}, data);
const importOptions = {
'demo_handle': request_data.demo_handle,
'step_name': request_data.step_name,
'file_counter': 1
};
const starterArray = new Array(2).fill(request_data.step_name);
function recursively_install_step_file() {
return import_demo_file(importOptions).then((res) => {
if('file_counter' in res.data && 'needs_resume' in res.data && res.data.needs_resume) {
importOptions.file_counter = res.data.file_counter; // should = be += ?
} else {
importOptions.file_counter++;
}
return res.data.keep_importing_more_files ? recursively_install_step_file() : res;
});
}
// the reduce/recurse pattern
return starterArray.reduce((previous_promise, next_step_identifier) => { // next_step_identifier is not used?
let importOptions.file_counter = 1; // reset to 1 at each stage of the reduction?
return previous_promise.then(response => {
if(response && ('finished_import' in response.data && response.data.finished_import || !response.success)) {
return response;
} else {
return recursively_install_step_file(); // execution will drop through to here on first iteration of the reduction
}
});
}, Promise.resolve());
}
可能不是100%正确,但是总体模式应该是正确的。准备为此做一些工作。