如何解决如何在节点js中正确使用await / async和for循环
我正在尝试提供一个功能,该功能将目录中的所有歌曲以及文件路径,持续时间和上次访问时间作为列表提供。尽管循环中的日志确实会打印出所需的内容,但响应是在循环完成之前发送的。
observation0:最后的日志发生在循环内的日志之前
router.get('/',function (req,res) {
let collection = new Array();
// glob returns an array 'results' containg the path of every subdirectory and file in the given location
glob("D:\\Music" + "/**/*",async (err,results) => {
// Filter out the required files and prepare them to be served in the required format by
for (let i = 0; i < results.length; i++) {
if (results[i].match(".mp3$") || results[i].match(".ogg$") || results[i].match(".wav$")) {
// To get the alst accessed time of the file: stat.atime
fs.stat(results[i],stat) => {
if (!err) {
// To get the duration if that mp3 song
duration(results[i],length) => {
if (!err) {
let minutes = Math.floor(length / 60)
let remainingSeconds = Math.floor(length) - minutes * 60
// The format to be served
let file = new Object()
file.key = results[i]
file.duration = String(minutes) + ' : ' + String(remainingSeconds)
file.lastListend = moment(stat.atime).fromNow()
collection.push(file)
console.log(collection) //this does log every iteration
}
})
}
})
}
}
console.log(collection); //logs an empty array
})
res.json({
allSnongs: collection
});
});
我无法理解文档的程度使我自己可以纠正代码:(
感谢您的帮助和建议
解决方法
此答案并不能解决您的代码,而只是为了消除所有误解:
fs.stat(path,callback); // fs.stat is always asynchronous.
// callback is not (normally),// but callback will run sometime in the future.
实现await
之类的功能(如fs.stat)的唯一方法是使用回调而不是promise,而是自己做出promise。
function promiseStat( path ){
return new Promise( ( resolve,reject ) => {
fs.stat( path,( err,stat ) => {
if( err ) reject( err );
else resolve( stat );
};
});
}
现在我们可以:
const stat = await promiseStat( path );
,
有相当多的时间来玩代码。
我会这样写,我做了很多更改。而且有效
srv.get('/',async function (req,res) {
// glob returns an array 'results' containg the path of every subdirectory and file in the given location
let results = await new Promise((res,rej) =>
glob("D:\\Music" + "/**/*",(err,results) => {
if (err != null) rej(err);
else res(results);
})
);
// Filter out the required files and prepare them to be served in the required format by
results = results.filter(
(result) =>
/\.mp3$/.test(result) ||
/\.ogg$/.test(result) ||
/\.wav$/.test(result)
);
const collection = await Promise.all(
results.map(async (result) => {
const stat = await new Promise((res,rej) =>
fs.stat(result,stat) => {
if (err != null) rej(err);
else res(stat);
})
);
const length = await new Promise((res,rej) =>
duration(result,length) => {
if (err != null) rej(err);
else res(length);
})
);
const minutes = Math.floor(length / 60);
const remainingSeconds = Math.floor(length) - minutes * 60;
// The format to be served
return {
key: result,duration: `${minutes} : ${remainingSeconds}`,lastListend: moment(stat.atime).fromNow(),};
})
);
console.log(collection);
res.json({
allSnongs: collection,});
});
给予
[
{
key: 'D:\Music\1.mp3',duration: '0 : 27',lastListend: 'a few seconds ago'
},{
key: 'D:\Music\1.mp3',duration: '0 : 52',duration: '2 : 12',lastListend: 'a few seconds ago'
}
]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。