如何在JavaScript的Array.filter回调中使用Promise作为过滤条件
问题描述
编辑: 解决方案在文末
我有大量需要按属性筛选的组件,当前遇到的问题是无法在Array.filter()方法中直接使用待resolve的Promise作为过滤条件。
以下是我当前的写法:
session.on("message_create", (msg) => { const matcher = new Matcher(msg); components .filter((c) => c.trigger == "message_create") .filter((c) => matcher.alias(c.alias)) .filter(async (c) => await matcher.scope(c.scope)) .forEach((c) => c.template(msg)); });
我不确定未完成resolve的Promise是否会被统一判定为真值?
以下是matcher.scope()的实现代码:
async scope(pattern?: string): Promise<boolean> { const chat = await this._msg.getChat(); const contact = await chat.getContact(); pattern = pattern ?? "anywhere"; if (pattern == "anywhere") { console.log("anywhere"); return true; } if (pattern == "group_only" && contact.isGroup) { console.log("group_only"); return true; } if (pattern == "private_only" && contact.isUser) { console.log("private_only"); return true; } return false; }
如果能同时帮我简化该方法的判断条件就更好了,谢谢。
编辑: 我把这个问题标记为重复问题,因为原有相关帖子帮我解决了问题,目前方案仍在优化,但已能满足使用需求
我最初尝试实现支持异步回调的数组过滤方法并返回this实现链式调用,但需要大量使用.then或await,复杂度远超预期。
之后我尝试封装接口,用同步方法处理链式逻辑、构建promise调用链并返回this,最终实现如下:
class Handler { constructor(array) { this.array = array this.queue = Promise.resolve(this.array) } async asyncFilter(acall, array) { let aux = [] for (let item of array) await acall(item) && aux.push(item) return aux } filter(acall) { this.queue = this.queue.then(array => this.asyncFilter(acall, array)) return this } async resolve() { let aux = await this.queue this.queue = Promise.resolve(this.array) return aux } }
测试代码:
async function main() { let handler = new Handler([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) let result1 = handler .filter(elem => elem % 2 == 0) .filter(elem => elem > 5) console.log(await result1.resolve()) let result2 = handler .filter(async elem => elem % 2 != 0) .filter(async elem => elem > 5) console.log(await result2.resolve()) let result3 = handler .filter(elem => elem % 2 != 0) .filter(elem => elem < 5) console.log(await result3.resolve()) } main()
运行结果:
PS C:\Users\Smith\Desktop\Javascript\Async> node .\main.js [ 6, 8, 10 ] [ 7, 9 ] [ 1, 3 ]
感谢所有提供帮助的人,我后续会继续优化代码、补充错误处理逻辑,谢谢大家。
内容的提问来源于stack exchange,提问作者Smith
相关产品推荐
相关产品推荐

