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

Why can't I use then on a resolved promise?

我有我的功能,它的工作是遍历许多文件(使用数组中的值作为文件名的构建块)并使用 reduce 下载它们。到目前为止,它更像是一个 hack,但 Promise 逻辑应该有效。除了它 doesn.t

这是我的代码:

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 允许我从 promise 链中退出的方式,但我不知道如何正确地解决我的 promise 链,很明显,它在未解决时被标记为已解决。

我想做 import_call.then(... 但目前还行不通,由于 import_demo_files.[=19 中的处理不当,它在实际完成之前就在此处执行了这段代码=]

归约中的异步递归并不是最简单的事情,而且你想要假设递归的每次迭代都与其他迭代相同的原因并不是很明显。

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