在内部承诺解决之前承诺解决

promise resolve before inner promise resolved

我有一个承诺,我希望只有当内心的承诺已经解决时它才会解决。现在它在 "loadend" 回调中到达 "resolve" 函数之前解析。

我错过了什么?我对您应该使用 resolve 的方式以及如何在另一个 promise 中使用一个 promise 感到困惑。

我在网上找不到任何有用的东西。

在下面的示例中,我基本上加载了一堆文件,对于每个文件,我得到一个 blob,我想将这个 blob 传递到文件 reader。

所有文件都传递给文件 reader 后,我想转到承诺链中的下一个函数。

现在它会转到链中的下一个函数,而无需等待 resolve 被调用。

var list = [];
var urls = this.files;

urls.forEach(function(url, i) {
    list.push(
        fetch(url).then(function(response) {
            response.blob().then(function(buffer) {

                var promise = new Promise(
                    function(resolve) {

                        var myReader = new FileReader();
                        myReader.addEventListener('loadend', function(e) {
                            // some time consuming operations
                            ...
                            window.console.log('yo');
                            resolve('yo');
                        });

                        //start the reading process.
                        myReader.readAsArrayBuffer(buffer);
                    });

                promise.then(function() {
                    window.console.log('smooth');
                    return 'smooth';
                });

            });
        })
    );
});

...

// run the promise...
Promise
    .all(list)
    .then(function(message){
        window.console.log('so what...?');
    })
    .catch(function(error) {
        window.console.log(error);
    });

当您不return then 回调中的任何内容时,它假定同步操作并立即使用结果 (undefined) 解决结果承诺。

您需要 return 来自每个异步函数的承诺 ,包括 then 您想要链接的回调。

具体来说,你的代码应该变成

var list = this.files.map(function(url, i) {
//                   ^^^^ easier than [] + forEach + push
    return fetch(url).then(function(response) {
        return response.blob().then(function(buffer) {
            return new Promise(function(resolve) {
                var myReader = new FileReader();
                myReader.addEventListener('loadend', function(e) {
                    …
                    resolve('yo');
                });
                myReader.readAsArrayBuffer(buffer);
            }).then(function() {
                window.console.log('smooth');
                return 'smooth';
            });
        })
    });
});

甚至更好,flattened:

var list = this.files.map(function(url, i) {
    return fetch(url).then(function(response) {
        return response.blob();
    }).then(function(buffer) {
        return new Promise(function(resolve) {
            var myReader = new FileReader();
            myReader.addEventListener('loadend', function(e) {
                …
                resolve('yo');
            });
            myReader.readAsArrayBuffer(buffer);
        });
    }).then(function() {
        window.console.log('smooth');
        return 'smooth';
    });
});