Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.JS:为什么嵌套的promise-thens似乎运行不正常?_Javascript_Node.js_Firebase_Promise_Firebase Storage - Fatal编程技术网

Javascript Node.JS:为什么嵌套的promise-thens似乎运行不正常?

Javascript Node.JS:为什么嵌套的promise-thens似乎运行不正常?,javascript,node.js,firebase,promise,firebase-storage,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(() => { mk

我需要分别运行每个下载和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);
我希望大then块会将下载操作添加到一个已经有所有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.

为什么foo/a/0.csv在调用所有bucket getFiles之前就开始下载?在已经有了getFiles thens之后,文件下载thens不应该被添加到队列的末尾吗?此外,foo/a有多个文件,那么为什么在getFiles调用之间只有一个文件下载潜入?

嵌套结构就是问题所在。 当所有外部循环都不在队列中时,没有任何机制可以防止内部循环向队列承诺。一旦创建第一个承诺,它将开始“工作”,并调用处理程序,因此,如果您没有完成添加所有承诺,并且第一个承诺再次到达将承诺添加到队列中的点,那么您将得到所观察到的结果

你的嵌套结构使它变得不可能。看一看。首先构建一个包含所有文件下载承诺的独特阵列。 使用Promise.all解析所有承诺后询问数组,然后将
then
处理程序附加到带有内部循环的Promise.all


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

您误解了Promises。你反复浏览你的网站名称,并将处理程序附加到你的承诺上。无论首先发生什么,它们都将异步执行。不过承诺队列中有js插件。我无法理解“但是既然您将处理程序附加到多个承诺”——哪些处理程序以及我在哪里做的?发生这种情况是因为第一个网站名mkdirp和getFiles在最外层的reduce循环完成运行之前就完成了吗?从而导致比赛状态?队列示例如何处理forEach循环(文件列表下载后,需要单独下载文件)?@pete我忽略了代码中的一些内容,但promise队列仍然适用。考虑以下情况。首先将所有处理程序连接到A。A立即开始工作,同时添加B,C现在处理程序A到达files.foreach块并向队列添加更多事件。A1,A2,A3然后加上D,E。。等等问题是没有什么可以阻止内部循环向队列中添加承诺。@pete我完全弄错了,但相应地更新了我的答案。试试看如果这没用,再提我一次,我们会解决的。@pete你解决了吗?