Javascript 在筛选器操作中使用async/await在第一次等待调用后不等待完成
对于特定的函数,需要从数据库中获取标签列表(RFID),但应检查各种表 问题的核心是长时间运行的操作在继续下一步之前没有等待完成 问题: 下面调用的代码运行如下(#数字对应下面代码中的数字):Javascript 在筛选器操作中使用async/await在第一次等待调用后不等待完成,javascript,node.js,asynchronous,filter,async-await,Javascript,Node.js,Asynchronous,Filter,Async Await,对于特定的函数,需要从数据库中获取标签列表(RFID),但应检查各种表 问题的核心是长时间运行的操作在继续下一步之前没有等待完成 问题: 下面调用的代码运行如下(#数字对应下面代码中的数字): 调用getAllTags(),启动程序 await db.dbRfid.findAll()返回X个有效结果(不是Promise对象) 开始筛选有效对象上的调用&wait finish(wait-place),因为其中的一些函数调用是异步调用 调用const driverTags=wait tag.getD
getAllTags()
,启动程序await db.dbRfid.findAll()
返回X个有效结果(不是Promise
对象)const driverTags=wait tag.getDrivers();
// #5
const truckTags = await tag.getTrucks();
实际上,对于每个allTags
项,调用getDrivers()
,退出filter()
,然后通过执行以下命令继续代码:
// #6
if (pureTags) {
return filteredTags;
}
问题:
据我所知,我正在等待ingasync
操作,但筛选器似乎只接受/允许一个async
操作
我想我做错了什么,但我无法找出问题的原因。任何建议都将不胜感激
下面的完整代码实现:
打电话给某人
const listOfTags = await getAllTags();
特定标签要求(所有有效、未使用、已启用和未撤销的标签)
问题代码:
// #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()
是一个创建的getter,它返回一个承诺
更新2
在evgeni fotia发表评论后
我最初有这段代码,但是选择不包括它,因为它可能会使事情变得复杂。然而,这是我尝试添加的wait Promise.all()
的原始代码
请注意,在运行此更新或原始问题中的代码后,我看到调试器点击getDrivers()
方法,然后(HTTP)响应被发送到客户端,并且仅在0.5~1s后我才看到getDrivers()
方法返回并继续下一个方法。正如T.J.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.resolve()
产生承诺
- 等待使用
Promise.all()解析所有这些内部承诺
产生了我相信@evgenifotia yup的相同问题,了解并尝试了承诺。所有。同样的结果,我选择只显示过滤器部分以更简洁。将发布承诺。所有作为更新,以解决任何问题或建议。您不能仅使用异步函数作为回调对于承诺不起任何作用的内容,async
函数返回。filter
只需检查返回是否为真实值——所有承诺实例都是真实值。如果您希望并行执行所有异步工作,可以使用map
构建承诺数组,然后promise.all
等待它们全部解决。如果您想一个接一个地执行这些操作,请使用for
或for of
循环并将推送到结果数组。FWIW,大致如下:@T.J.Crowder谢谢您的建议。我想使用map
但是,我觉得这会降低性能,因为调用getDrivers()
,然后调用getTrucks()
,等等,不检查是否drivers.length>0
。我在这里没有显示这一点,因为我修改了它来检查我是否得到了结果,但这是最初的意图。似乎我需要进行3x
调用,无论我希望避免什么。感谢您的练习(我想我已经这样做了…几乎;)
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
}
});
}
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
}));
};