Node.JS:为什么嵌套的promise这些似乎无法正常运行?

时间:2017-06-02 07:41:26

标签: javascript node.js firebase promise firebase-storage

我需要每次下载和getFiles调用单独运行,因为firebase似乎无法处理太多连接。

const bucket = storage.bucket(bucketName); // firebase storage bucket
var queue = Promise.resolve();

websiteNames.reduce(function(promise, websiteName) {
    return promise
    .then(() => {
        mkdirp(websiteName)
    })
    .then(() => {
        console.log("now getting files: " + dirPath);
        return bucket.getFiles({prefix: dirPath})
    })
    .then(data => {
        console.log("got files");
        var files = data[0];
        files.forEach(function (file) {
            var storePath = tmpDir + "/" + file.name;
            queue = queue
            .then(() => {
                console.log("now downloading: " + file.name);
                return file.download({destination: storePath});
            })
            .then(() => {
                console.log(`downloaded to ${storePath}.`);
                return readFile(storePath, 'utf8');
            })
            .then(buffer => {
                console.log("readed file: " + storePath + " of buf size " + buffer.length);
            });
        });
    });
}, queue);

我预计big then block会将下载操作添加到已经拥有所有getFiles操作的队列中。所以我希望它在开始下载文件之前进行所有getFiles调用。但控制台日志如下:

now getting files: foo/a
got files
now downloading: foo/a/0.csv
now getting files: foo/b
got files
now getting files: foo/c
got files
downloaded to /tmp/foo/a/0.csv.

为什么在进行所有存储桶getFiles调用之前foo / a / 0.csv开始下载?在已经拥有getFiles之后,文件下载是否已经被添加到队列的末尾了?而且foo / a有多个文件,为什么只有1个文件下载在getFiles调用之间潜入?

1 个答案:

答案 0 :(得分:1)

嵌套结构是个问题。 当所有外部循环尚未在队列中时,没有机制来阻止内循环承诺到队列。一旦你创建了第一个Promise,它就会开始#34; work"并且将调用处理程序,因此如果您还没有添加所有Promise,并且第一个Promise达到了将Promises再次添加到队列的位置,那么您将获得所观察到的内容。

你的嵌套结构是不可能的。看看Promise.all。首先使用所有文件下载Promises构建一个不同的Array。 使用Promise.all解决所有Promise已解决的问题,然后使用内部循环将then处理程序附加到Promise.all。

Promise.all将包含所有文件的数组,您可以通过构建另一个不同的队列来执行更多步骤。