我正在链接一系列与数据库一起操作的承诺。从第一个承诺中,我检索到一个对象数组。在第二个承诺中,我为每个对象生成一个承诺。然后,我过滤结果。下面是一个代码示例:
db.getUser(user)
.then(user=> Promise.all(
user.shirts.map(userShirt => db.getShirt(shirt.id))
) as Promise<IShirt[]>)
.then(shirts => {
shirts = shirts.filter(shirt => shirt.color === 'blue');
console.log(shirts);
})
.catch(err => {
console.log(err);
});
这是我的代码所做工作的简化示例。问题出在过滤器操作中,我检索了一个 0 长度的数组。知道吗?
收集调用getShirt
所产生的承诺,然后将它们一起运行。所有承诺将产生这些承诺的一系列决议。
编辑我看到你确实有一个承诺。 简单的解决方案是修复未定义的临时变量名称:
user.shirts.map(userShirt => db.getShirt(shirt.id)) // shirt is undefined
user.shirts.map(userShirt => db.getShirt(userShirt.id))
这是在检索 0 长度数组时修复filter
操作的方式。
其中一个变量名称已关闭:
db.getUser(user)
.then(user=> Promise.all(
user.shirts.map(userShirt => db.getShirt(shirt.id)) // <- perhaps you meant `userShirt.id` here?
))
.then(shirts => {
shirts = shirts.filter(shirt => shirt.color === 'blue')
console.log('shirts')
})
.catch(err => {
console.error(err),
})
你可以接受这一点,尽管这里更大的问题是首先必须担心Promise.all
。我写了一个库,所以你不必担心样板承诺代码。
下面是与使用我的库中的函数pipe
、map
、filter
、get
和eq
编写的示例等效的代码:
const db = {} // your db instance here
const getBlueShirts = pipe([
db.getUser,
get('shirts'),
map(pipe([get('id'), db.getShirt])),
filter(eq('blue', get('color'))),
])
tryCatch(getBlueShirts, console.error)(user)
此外,您可以使用transform
一举map
和filter
。当你使用transform
时,map(...)
和filter(...)
成为由pipe
组成的换能器。
const getBlueShirts = pipe([
db.getUser,
get('shirts'),
transform(pipe([ // pipe([map(...), filter(...)]) is a transducer
map(pipe([get('id'), db.getShirt])),
filter(eq('blue', get('color'))),
]), [])
])
我在这里写更多关于换能器的信息