为什么我不能在已解决的承诺上使用then?

时间:2019-06-25 14:58:36

标签: javascript promise es6-promise

我的职能是遍历多个文件(这些文件将数组中的值用作文件名的构建块)并使用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中的处理不当,它在实际执行之前在这里执行了此代码。

1 个答案:

答案 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%正确,但是总体模式应该是正确的。准备为此做一些工作。