对于特定功能,需要数据库中的标签(RFID)列表,但应检查各种表。
该问题集中在长期运行的问题上,该问题await
在继续进行下一个之前就没有完成。
问题:
下面调用的代码按如下方式运行(#数字与下面代码中的数字相对应):
getAllTags()
被调用,启动过程await db.dbRfid.findAll()
返回有效数量为X的有效结果(不是Promise
对象)const driverTags = await tag.getDrivers();
在这一点上,希望该函数返回结果并继续执行下一个函数,即
// #5
const truckTags = await tag.getTrucks();
实际上发生的是每个allTags
项目,getDrivers()
被调用和filter()
退出,并且代码继续执行下一个步骤:
// #6
if (pureTags) {
return filteredTags;
}
题:
据我了解,我await
荷兰国际集团async
正常运作,但它似乎像过滤器仅接受/允许一个async
操作。
我以为我做错了什么,但我无法确定问题的原因。任何意见,将不胜感激!
完整的代码实现如下:
用例如调用
const listOfTags = await getAllTags();
特定标签要求(所有有效,未使用,已启用和已撤销的标签)
const listOfTags = await getAllTags(false, true, true, true);
问题代码:
// #1
const getAllTags = async (pureTags = false, unused = true, enabled = true, notRevoked = false) => {
// #2
let allTags = await db.dbRfid.findAll()
// #3
let filteredTags = await allTags.filter(async tag => {
// check tag used
if (unused) {
// #4
const driverTags = await tag.getDrivers();
// #5
const truckTags = await tag.getTrucks();
const userTags = await tag.getUsers();
if (driverTags.length > 0) {
return false;
}
if (truckTags.length > 0) {
return false;
}
if (userTags.length > 0) {
return false;
}
}
// check tag enabled
if (enabled && !tag.enabled) {
return false;
}
// check tag revoked or return true
return notRevoked && !tag.revoked;
});
// return tags as is
// #6
if (pureTags) {
return filteredTags;
}
return filteredTags.map(tag => {
return {
id: tag.id,
rfid: tag.rfid,
expiryDate: tag.expiryDate,
revoked: tag.revoked,
enabled: tag.enabled
}
});
}
更新资料
我应该提一下:
.getDrivers()
是由sequelize创建的吸气剂,该吸气剂返回承诺。更新2
经过评论 evgeni fotia
我最初有这段代码,但是选择不包含它,因为它可能会处理一些复杂的事情。但是,这是我尝试添加的原始代码await Promise.all()
。
const getAllTags = async (pureTags = false, unused = true, enabled = true, notRevoked = false) => {
let allTags = await db.dbRfid.findAll()
let filteredTags = await Promise.all(
// await allTags.filter(async tag => { //tried the await here too - for good measure
allTags.filter(async tag => {
// check tag used
if (unused) {
const driverTags = await tag.getDrivers();
const truckTags = await tag.getTrucks();
const userTags = await tag.getUsers();
if (driverTags.length > 0) {
return false;
}
if (truckTags.length > 0) {
return false;
}
if (userTags.length > 0) {
return false;
}
}
// check tag enabled
if (enabled && !tag.enabled) {
return false;
}
// check tag revoked or return true
return notRevoked && !tag.revoked;
})
);
// return tags as is
if (pureTags) {
return filteredTags;
}
return filteredTags.map(tag => {
return {
id: tag.id,
rfid: tag.rfid,
expiryDate: tag.expiryDate,
revoked: tag.revoked,
enabled: tag.enabled
}
});
}
请注意,在此更新中或原始问题中运行代码后,我看到调试器点击了该getDrivers()
方法,然后将(HTTP)响应发送到客户端,并且仅在0.5〜1s之后,我看到该getDrivers()
方法返回并继续执行下一个方法。
正如TJ Chowder所评论的那样,您的中心问题是,您正在尝试的.filter()
东西有时是布尔值,有时是诺言。
您应该以不同的步骤进行映射和过滤。我倾向于使用.then()
语法,因此这是我的方法:
const getAllTags = (pureTags = false, unused = true, enabled = true, notRevoked = false) => {
return db.dbRfid.findAll()
.then(allTags => allTags.map(tag => Promise.resolve(
enabled === tag.enabled && notRevoked === !tag.revoked && Promise.all([
tag.getDrivers(), tag.getTrucks(), tag.getUsers()
]).then(results => results.some(r => r.length))
).then(ok => ok ? tag : null)))
.then(pendingTags => Promise.all(pendingTags))
.then(resolvedTags => resolvedTags.filter(tag => tag))
.then(filteredTags => filteredTags.map(tag => pureTags ? tag : {
id: tag.id,
rfid: tag.rfid,
expiryDate: tag.expiryDate,
revoked: tag.revoked,
enabled: tag.enabled
}));
};
此代码的逻辑:
Promise<Tag[]>
null
根据我们发现使用的条件Promise.resolve()
来解决该检查产生的潜在(*)异步性质Promise<Promise<Tag|null>[]>
Promise.all()
<Promise<(Tag|null)[]>
null
的值(即标签,我们不希望)<Promise<Tag[]>
pureTags
<Promise<(Tag|object)[]>
(*)的Promise.all()
,如果前提条件检查时才会激活,因短路。如果不是,则只是一个立即Promise.resolve(false)
解析为的false
。在另一种情况下,它将与Promise.resolve(<Promise<Boolean>)
完全相同Promise.resolve(Boolean)
。这样我们可以统一同步测试和异步测试。
在随后的步骤中,.then()
我们可以决定是否返回tag
-或null
,以指示此标记未通过过滤条件。在null
随后的值由挑选出来resolvedTags.filter(tag => tag)
。
请注意,您的代码序列化三个异步检查(getDrivers
,getTrucks
,getUsers
),因为下开始之前,每个等待。使用Promise.all()
让它们并行运行,这是我不喜欢async
/await
进行一切操作的原因之一。
我将其重写为async
/ await
style作为练习。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句