使用来自asynchronous函数的数据

我有关于asynchronous函数的问题,以及函数返回结果后如何发送。 这是我想要完成的:

在节点中处理GET请求的过程中,读取文件夹的内容,并返回该文件夹中的文件。 接下来,我想遍历该文件夹中每个文件的统计信息,仅加载在特定时间段内创build的文件,最后将这些文件中的数据作为对请求的响应发送。 它看起来像这样:

array = [] fs.readdir(path, function(err, items) { items.forEach(function(item) { fs.stat(path, function(err, stats) { if (period check) { array.push(data) } }) }) } res.send(array) 

这种方法最终发送一个空的数组,我已经看到Promises,这似乎是解决scheme,但我不能让他们在这种情况下工作。 使用fs.statSync而不是fs.stat可以工作,但是这大大降低了性能,感觉应该可以通过Promise实现,但是我不知道如何实现。

有没有人为此提供解决scheme?


编辑:关于标记为重复的问题,我试图解决我的问题,首先在那里的答案,但没有成功。 我的问题有一些嵌套函数和循环,比那里给出的例子更复杂。

如果您更喜欢基于Promise的方法,请使用此方法:

 var path = require('path') fs.readdir(myPath, function(err, items) { var array = []; Promise.all(items.map(function(item) { return new Promise(function(resolve, reject) { fs.stat(path.resolve(myPath, item), function(err, stats) { if (err) { return reject(err) } if (/* period check */) { array.push(data) } resolve() }) }) })).then(function() { res.send(array) }).catch(function(error) { // error handling res.sendStatus(500) }) } 

这是我会build议的。

 // This is a new API and you might need to use the util.promisify // npm package if you are using old node versions. const promisify = require('util').promisify; const fs = require('fs'); // promisify transforms a callback-based API into a promise-based one. const readdir = promisify(fs.readdir); const stat = promisify(fs.stat); const dataProm = readdir(path) .then((items) => { // Map each items to a promise on its stat. const statProms = items.map(path => fs.stat(path); // Wait for all these promises to resolve. return Promise.all(statProms); }) // Remove undesirable file stats based on the result // of period check. .then(stats => stats.filter(stat => periodCheck(stat))); // dataProm will resolve with your data. You might as well return it // as is. But if you need to use `res.send`, you can do: dataProm.then((data) => { res.send(data); }, (err) => { // If you go away from the promise chain, you need to handle // errors now or you are silently swallowing them. res.sendError(err); });