我需要每个 download 和 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 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.
为什么 foo/a/0.csv 在所有存储桶 getFiles 调用完成之前就开始下载?在已经有 getFiles thens 之后,文件下载 thens 不应该被添加到队列的末尾吗?此外 foo/a 有多个文件,那么为什么在 getFiles 调用之间只下载了 1 个文件?
最佳答案
嵌套结构是问题所在。 当所有外部循环尚未进入队列时,没有机制可以阻止内部循环向队列 promise 。一旦你创建了第一个 Promise,它就会开始“工作”,并且处理程序将被调用,因此,如果你没有完成添加所有 Promise,并且第一个 Promise 达到了再次将 Promise 添加到队列的程度,你就会得到你所观察到的结果。
你的嵌套结构使得它变得不可能。看看Promise.all 。首先使用所有文件下载 promise 构建一个不同的数组。
当所有 Promise.all 都已解决时询问数组,然后使用内部循环将 then
处理程序附加到 Promise.all。
Promise.all 将有一个包含所有文件的数组,您可以通过构建另一个不同的队列来使用它来执行更多步骤。
关于javascript - Node.JS:为什么嵌套的 Promise then 似乎乱序了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44323402/