javascript - 在 for 循环中使用 Promise
问题描述
我正在尝试遍历一系列日期以返回每个日期的热门歌曲。所以我有一个 for 循环。在这个 for 循环中,调用了一个函数来查看我的数据库中的热门歌曲。因此,我将它包装在一个 Promise 中,以便它支持 for 循环,但这种方法似乎也不起作用。有人可以解释一个更好的方法来解决这个问题。
app.post('/getDate', function (req, res) {
this.tracks = [];
let until = new Date(req.body.dateToOutput);
for (var d = new Date(req.body.dateFromOutput); d <= until; d.setDate(d.getDate() + 1)) {
date = d.toLocaleDateString('en-US', { timeZone: 'UTC' });
console.log('date', date);
new Promise(function (resolve, reject) {
getDate(date).then(() => {
resolve();
})
});
}
console.log(this.tracks);
});
function getDate(date) {
return new Promise(function (resolve, reject) {
Track.find({ Date: date }, function (err, track) {
if (!err) {
console.log(track);
this.tracks.push(track);
resolve();
}
else {
reject();
}
}).sort({ Streams: -1 }).limit(1);
});
}
解决方案
我认为诺言没有被执行,而且我认为您在 getDate 函数中指向一个未定义的对象,并且 for 循环不会等待解决或拒绝的诺言。看到这个:
new Promise(function (resolve, reject) {
getDate(date).then(() => {
resolve();
})
});
你正在创建一个新的承诺,但你从未执行过这个承诺。
同样在函数中,getDate
您指向的对象在他的上下文中不存在:
this.tracks.push(track);
这会给您带来一些错误,因为this.tracks
不是getDate
函数的一部分,而是该方法调用的匿名函数的一部分app.post
。
this.tracks
因此,您必须返回轨道本身,而不是直接推入:
if (!err) {
console.log(track);
resolve(track);
}
那么你应该使用 async - await 来强制循环在承诺处暂停,直到这个被解决或拒绝,所以你的匿名函数现在应该是一个异步匿名函数才能使用 await,你也不需要另一个承诺中的承诺包装,我的意思是你不需要这个:
new Promise(function (resolve, reject) {
getDate(date).then(() => {
resolve();
})
});
你只需要这个:
getDate(date).then(() => {
resolve();
})
因为 getDate() 函数本身返回一个承诺。
所以这就是你的代码在进行所有这些更改后的样子:
const response = app.post('/getDate', async function (req, res) {
this.tracks = [];
let until = new Date(req.body.dateToOutput);
for (var d = new Date(req.body.dateFromOutput); d <= until; d.setDate(d.getDate() + 1)) {
date = d.toLocaleDateString('en-US', { timeZone: 'UTC' });
console.log('date', date);
const ctrack = await getDate(date);
this.tracks.push(ctrack);
}
console.log(this.tracks);
return this.tracks;
});
function getDate(date) {
return new Promise(function (resolve, reject) {
Track.find({ Date: date }, function (err, track) {
if (!err) {
console.log(track);
resolve(track);
}
else {
reject();
}
}).sort({ Streams: -1 }).limit(1);
});
}
现在您将响应作为一个承诺,因为异步函数返回一个承诺......然后您可以捕获它并使用响应:
response.then(trackList =>{
console.log(trackList);
}).catch(()=>{
console.error("something went wrong...!");
})
推荐阅读
- woocommerce - 在邮政编码限制下始终允许在 WooCommerce 中本地取货
- node.js - dialogflow webhook 不考虑使用fulfillmentText、fulfillmentMessages 的有效负载
- python-3.x - 如何将生成器与 JSON 树合并
- wix - 使用相对路径在 WiX 安装程序中创建符号链接
- javascript - 如何调整文本大小以适合容器
- c++ - std::bind 与可变参数模板和自动返回类型
- jsonschema - jsonschema中的items和properties有什么区别?
- c# - 如何为 msbuild 安装 nuget.build.tasks.pack.targets
- jquery - 如何使用 jQuery 删除名称无效的属性
- javascript - 语法错误:意外的标记 '<'