[英]bluebird - function returns promise objects instead of actual data
Following this snippet I am trying to write a function that loops trough a directory, finds directories, and reads xml file names from those directories (I know that the folder structure will always remain the same). 在这个片段之后,我试图编写一个循环通过目录,查找目录,并从这些目录中读取xml文件名的函数(我知道文件夹结构将始终保持不变)。 So far my function is working as expected, but when I try to get the return from the function I just get Promise objects.
到目前为止,我的函数正在按预期工作,但是当我尝试从函数返回时,我只得到Promise对象。
My code: 我的代码:
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
const path = require('path');
function getFileNames(rootPath) {
// Read content of path
return fs.readdirAsync(rootPath)
// For every file in path
.then(function(directories) {
// Filter out the directories
return directories.filter(function(file) {
return fs.statSync(path.join(rootPath, file)).isDirectory();
});
})
// For every directory
.then(function(directories) {
return directories.map(function(directory) {
// Read file in the directory
return fs.readdirAsync(path.join(rootPath, directory))
.filter(function(file) {
return path.extname(file) == '.XML';
})
.then(function(files) {
// Do something with the files
return files;
});
});
});
}
getFileNames('./XML').then(function(files) {
console.log(files);
});
When I console.log(files)
inside the last .then
function inside getFileNames
, I get the actual arrays of file names in the console. 当我
console.log(files)
最后的内部.then
内部功能getFileNames
,我得到的文件名的实际阵列控制台。 But when I run the code above I get this output: 但是当我运行上面的代码时,我得到了这个输出:
[ Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined },
Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined },
Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined },
Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined },
Promise {
_bitField: 0,
_fulfillmentHandler0: undefined,
_rejectionHandler0: undefined,
_promise0: undefined,
_receiver0: undefined } ]
Why is this happening and how to fix it? 为什么会发生这种情况以及如何解决?
In the lines 在线
.then(function(directories) {
return directories.map(function(directory) {
return fs.readdirAsync…
you are creating a promise for an array of promises, and that's exactly what you're getting in your final log. 你正在为一系列承诺创造一个承诺,而这正是你在最终日志中得到的。 Instead of returning an array of promises, you need to return a promise for an array of values - and
Promise.all
is exactly what does that: 而不是返回一个promises数组,你需要返回一个值数组的promise - 而
Promise.all
正是这样做的:
.then(function(directories) {
return Promise.all(directories.map(function(directory) {
return fs.readdirAsync(…)
…
}));
})
However, in Bluebird it would be more idiomatic to use Promise.map(directories, function(…) { … })
or even the map
method (similar to how you already used .filter
did on the files in each directory): 但是,在Bluebird中,使用
Promise.map(directories, function(…) { … })
甚至是map
方法 (类似于你已经使用.filter
对每个目录中的文件.filter
那样Promise.map(directories, function(…) { … })
会更加惯用:
function getFileNames(rootPath) {
return fs.readdirAsync(rootPath)
.filter(function(file) {
return fs.statAsync(path.join(rootPath, file)).then(function(s) {
return s.isDirectory();
});
})
.map(function(directory) {
//^^^^
return fs.readdirAsync(path.join(rootPath, directory))
.filter(function(file) {
return path.extname(file) == '.XML';
})
.map(function(file) {
// Do something with every file
return file;
});
});
}
try this 试试这个
return getFileNames('./XML').then(function(files) {
console.log(files);
return files;
});
This piece of code: 这段代码:
.then(function(directories) {
return directories.map(function(directory) {
return fs.readdirAsync(path.join(rootPath, directory))
...
will return an array of promises to the then callback. 将返回一个promises数组到当时的回调。 An array of promises count as an immediate value here, will not be coerected to a Promise of an array.
Promise数组在此处计为立即值,不会与数组的Promise相关联。 To convert an array of promises to a promise of an array you could use
Promise.all
, but since you are using bluebird, you have a better option: 要将
Promise.all
数组转换为数组的promise,可以使用Promise.all
,但是由于您使用的是bluebird,因此您有更好的选择:
All you have to do is to use Promise.map
: 您所要做的就是使用
Promise.map
:
.then(function(directories) {
return Promise.map(directories, function(directory) {
return fs.readdirAsync(path.join(rootPath, directory))
...
Figured it out, there was one .then too much on the second function: 弄清楚,第二个函数有一个。然后太多了:
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
const path = require('path');
function getFileNames(rootPath) {
// Read content of path
return fs.readdirAsync(rootPath)
.then(function(content) {
return content.filter(function(file) {
return fs.statSync(path.join(rootPath, file)).isDirectory();
});
})
// For every directory
.map(function(directory) {
// Read files in the directory
return fs.readdirAsync(path.join(rootPath, directory))
.filter(function(file) {
return path.extname(file) == '.XML';
});
});
}
getFileNames('./XML').then(function(files) {
console.log(files);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.